package redis import ( "sync" goredis "github.com/redis/go-redis/v9" "github.com/zeromicro/go-zero/core/stores/redis" ) // PubSubClient returns a lazily constructed *go-redis Client used for // Pub/Sub subscriptions. go-zero's wrapper does not expose Subscribe, so // permission/notification modules that need Pub/Sub call this helper. // // The connection is independent from the go-zero connection pool because // Subscribe holds the connection for the subscription lifetime; mixing // them with the go-zero pool's command path would break the pool. func (c *Client) PubSubClient() *goredis.Client { if c == nil || c.r == nil { return nil } c.psMu.Lock() defer c.psMu.Unlock() if c.ps != nil { return c.ps } addr := c.r.Addr user := c.r.User pass := c.r.Pass c.ps = goredis.NewClient(&goredis.Options{ Addr: addr, Username: user, Password: pass, }) return c.ps } // ClosePubSub closes the lazy-loaded Pub/Sub client (if any). Safe to call // even when never opened. func (c *Client) ClosePubSub() error { if c == nil { return nil } c.psMu.Lock() defer c.psMu.Unlock() if c.ps == nil { return nil } err := c.ps.Close() c.ps = nil return err } // pubSubFields are the lazy state for PubSub. Lives here so client.go // stays minimal; the struct is augmented via the embedded fields below. type pubSubFields struct { psMu sync.Mutex ps *goredis.Client } // reference to redis.Redis so the package compiles when only pubsub.go is // edited. The actual struct definition is in client.go. var _ = (*redis.Redis)(nil)