mirror of
https://github.com/redis/go-redis.git
synced 2025-07-28 06:42:00 +03:00
feat: add VoidPushNotificationProcessor for disabled push notifications
- Add VoidPushNotificationProcessor that reads and discards push notifications - Create PushNotificationProcessorInterface for consistent behavior - Always provide a processor (real or void) instead of nil - VoidPushNotificationProcessor properly cleans RESP3 push notifications from buffer - Remove all nil checks throughout codebase for cleaner, safer code - Update tests to expect VoidPushNotificationProcessor when disabled Benefits: - Eliminates nil pointer risks throughout the codebase - Follows null object pattern for safer operation - Properly handles RESP3 push notifications even when disabled - Consistent interface regardless of push notification settings - Cleaner code without defensive nil checks everywhere
This commit is contained in:
39
redis.go
39
redis.go
@ -209,7 +209,7 @@ type baseClient struct {
|
||||
onClose func() error // hook called when client is closed
|
||||
|
||||
// Push notification processing
|
||||
pushProcessor *PushNotificationProcessor
|
||||
pushProcessor PushNotificationProcessorInterface
|
||||
}
|
||||
|
||||
func (c *baseClient) clone() *baseClient {
|
||||
@ -535,7 +535,7 @@ func (c *baseClient) _process(ctx context.Context, cmd Cmder, attempt int) (bool
|
||||
}
|
||||
if err := cn.WithReader(c.context(ctx), c.cmdTimeout(cmd), func(rd *proto.Reader) error {
|
||||
// Check for push notifications before reading the command reply
|
||||
if c.opt.Protocol == 3 && c.pushProcessor != nil && c.pushProcessor.IsEnabled() {
|
||||
if c.opt.Protocol == 3 && c.pushProcessor.IsEnabled() {
|
||||
if err := c.pushProcessor.ProcessPendingNotifications(ctx, rd); err != nil {
|
||||
internal.Logger.Printf(ctx, "push: error processing push notifications: %v", err)
|
||||
}
|
||||
@ -772,9 +772,7 @@ func NewClient(opt *Options) *Client {
|
||||
c.initializePushProcessor()
|
||||
|
||||
// Update options with the initialized push processor for connection pool
|
||||
if c.pushProcessor != nil {
|
||||
opt.PushNotificationProcessor = c.pushProcessor
|
||||
}
|
||||
opt.PushNotificationProcessor = c.pushProcessor
|
||||
|
||||
c.connPool = newConnPool(opt, c.dialHook)
|
||||
|
||||
@ -819,8 +817,11 @@ func (c *Client) initializePushProcessor() {
|
||||
if c.opt.PushNotificationProcessor != nil {
|
||||
c.pushProcessor = c.opt.PushNotificationProcessor
|
||||
} else if c.opt.PushNotifications {
|
||||
// Create default processor only if push notifications are enabled
|
||||
// Create default processor when push notifications are enabled
|
||||
c.pushProcessor = NewPushNotificationProcessor(true)
|
||||
} else {
|
||||
// Create void processor when push notifications are disabled
|
||||
c.pushProcessor = NewVoidPushNotificationProcessor()
|
||||
}
|
||||
}
|
||||
|
||||
@ -828,14 +829,11 @@ func (c *Client) initializePushProcessor() {
|
||||
// Returns an error if a handler is already registered for this push notification name.
|
||||
// If protected is true, the handler cannot be unregistered.
|
||||
func (c *Client) RegisterPushNotificationHandler(pushNotificationName string, handler PushNotificationHandler, protected bool) error {
|
||||
if c.pushProcessor != nil {
|
||||
return c.pushProcessor.RegisterHandler(pushNotificationName, handler, protected)
|
||||
}
|
||||
return nil
|
||||
return c.pushProcessor.RegisterHandler(pushNotificationName, handler, protected)
|
||||
}
|
||||
|
||||
// GetPushNotificationProcessor returns the push notification processor.
|
||||
func (c *Client) GetPushNotificationProcessor() *PushNotificationProcessor {
|
||||
func (c *Client) GetPushNotificationProcessor() PushNotificationProcessorInterface {
|
||||
return c.pushProcessor
|
||||
}
|
||||
|
||||
@ -886,10 +884,8 @@ func (c *Client) pubSub() *PubSub {
|
||||
}
|
||||
pubsub.init()
|
||||
|
||||
// Set the push notification processor if available
|
||||
if c.pushProcessor != nil {
|
||||
pubsub.SetPushNotificationProcessor(c.pushProcessor)
|
||||
}
|
||||
// Set the push notification processor
|
||||
pubsub.SetPushNotificationProcessor(c.pushProcessor)
|
||||
|
||||
return pubsub
|
||||
}
|
||||
@ -974,10 +970,8 @@ func newConn(opt *Options, connPool pool.Pooler, parentHooks *hooksMixin) *Conn
|
||||
c.hooksMixin = parentHooks.clone()
|
||||
}
|
||||
|
||||
// Set push notification processor if available in options
|
||||
if opt.PushNotificationProcessor != nil {
|
||||
c.pushProcessor = opt.PushNotificationProcessor
|
||||
}
|
||||
// Set push notification processor from options (always available now)
|
||||
c.pushProcessor = opt.PushNotificationProcessor
|
||||
|
||||
c.cmdable = c.Process
|
||||
c.statefulCmdable = c.Process
|
||||
@ -1001,14 +995,11 @@ func (c *Conn) Process(ctx context.Context, cmd Cmder) error {
|
||||
// Returns an error if a handler is already registered for this push notification name.
|
||||
// If protected is true, the handler cannot be unregistered.
|
||||
func (c *Conn) RegisterPushNotificationHandler(pushNotificationName string, handler PushNotificationHandler, protected bool) error {
|
||||
if c.pushProcessor != nil {
|
||||
return c.pushProcessor.RegisterHandler(pushNotificationName, handler, protected)
|
||||
}
|
||||
return nil
|
||||
return c.pushProcessor.RegisterHandler(pushNotificationName, handler, protected)
|
||||
}
|
||||
|
||||
// GetPushNotificationProcessor returns the push notification processor.
|
||||
func (c *Conn) GetPushNotificationProcessor() *PushNotificationProcessor {
|
||||
func (c *Conn) GetPushNotificationProcessor() PushNotificationProcessorInterface {
|
||||
return c.pushProcessor
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user