Skip to content

Commit 7dedd88

Browse files
committed
feat: remove global handlers and enable push notifications by default
- Remove all global push notification handler functionality - Simplify registry to support only single handler per notification type - Enable push notifications by default for RESP3 connections - Update comprehensive test suite to remove global handler tests - Update demo to show multiple specific handlers instead of global handlers - Always respect custom processors regardless of PushNotifications flag Push notifications are now automatically enabled for RESP3 and each notification type has a single dedicated handler for predictable behavior.
1 parent 6db3b24 commit 7dedd88

File tree

5 files changed

+50
-212
lines changed

5 files changed

+50
-212
lines changed

example/push-notification-demo/main.go

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ func main() {
1818
// Example 2: Custom push notification handlers
1919
customHandlersExample()
2020

21-
// Example 3: Global push notification handlers
22-
globalHandlersExample()
21+
// Example 3: Multiple specific handlers
22+
multipleSpecificHandlersExample()
2323

2424
// Example 4: Custom push notifications
2525
customPushNotificationExample()
@@ -95,8 +95,8 @@ func customHandlersExample() {
9595
fmt.Println(" - SYSTEM_ALERT: Handles system alert notifications")
9696
}
9797

98-
func globalHandlersExample() {
99-
fmt.Println("\n=== Global Push Notification Handler Example ===")
98+
func multipleSpecificHandlersExample() {
99+
fmt.Println("\n=== Multiple Specific Handlers Example ===")
100100

101101
client := redis.NewClient(&redis.Options{
102102
Addr: "localhost:6379",
@@ -105,25 +105,21 @@ func globalHandlersExample() {
105105
})
106106
defer client.Close()
107107

108-
// Register a global handler that receives ALL push notifications
109-
client.RegisterGlobalPushNotificationHandlerFunc(func(ctx context.Context, notification []interface{}) bool {
110-
if len(notification) > 0 {
111-
command := notification[0]
112-
fmt.Printf("📡 Global handler received: %v (args: %d)\n", command, len(notification)-1)
113-
}
108+
// Register specific handlers
109+
client.RegisterPushNotificationHandlerFunc("SPECIFIC_EVENT", func(ctx context.Context, notification []interface{}) bool {
110+
fmt.Printf("🎯 Specific handler for SPECIFIC_EVENT: %v\n", notification)
114111
return true
115112
})
116113

117-
// Register specific handlers as well
118-
client.RegisterPushNotificationHandlerFunc("SPECIFIC_EVENT", func(ctx context.Context, notification []interface{}) bool {
119-
fmt.Printf("🎯 Specific handler for SPECIFIC_EVENT: %v\n", notification)
114+
client.RegisterPushNotificationHandlerFunc("ANOTHER_EVENT", func(ctx context.Context, notification []interface{}) bool {
115+
fmt.Printf("🎯 Specific handler for ANOTHER_EVENT: %v\n", notification)
120116
return true
121117
})
122118

123-
fmt.Println("✅ Global and specific handlers registered:")
124-
fmt.Println(" - Global handler will receive ALL push notifications")
125-
fmt.Println(" - Specific handler will receive only SPECIFIC_EVENT notifications")
126-
fmt.Println(" - Both handlers will be called for SPECIFIC_EVENT notifications")
119+
fmt.Println("✅ Specific handlers registered:")
120+
fmt.Println(" - SPECIFIC_EVENT handler will receive only SPECIFIC_EVENT notifications")
121+
fmt.Println(" - ANOTHER_EVENT handler will receive only ANOTHER_EVENT notifications")
122+
fmt.Println(" - Each notification type has a single dedicated handler")
127123
}
128124

129125
func customPushNotificationExample() {
@@ -143,24 +139,9 @@ func customPushNotificationExample() {
143139
return true
144140
})
145141

146-
// Register a global handler to monitor all notifications
147-
client.RegisterGlobalPushNotificationHandlerFunc(func(ctx context.Context, notification []interface{}) bool {
148-
if len(notification) > 0 {
149-
command := notification[0]
150-
switch command {
151-
case "MOVING", "MIGRATING", "MIGRATED":
152-
fmt.Printf("🔄 Cluster notification: %v\n", command)
153-
default:
154-
fmt.Printf("📨 Other notification: %v\n", command)
155-
}
156-
}
157-
return true
158-
})
159-
160142
fmt.Println("✅ Custom push notifications enabled:")
161-
fmt.Println(" - MOVING, MIGRATING, MIGRATED notifications → Cluster handlers")
162143
fmt.Println(" - APPLICATION_EVENT notifications → Custom handler")
163-
fmt.Println(" - All notifications → Global monitoring handler")
144+
fmt.Println(" - Each notification type has a single dedicated handler")
164145
}
165146

166147
func multipleNotificationTypesExample() {

options.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,11 @@ type Options struct {
221221
// When enabled, the client will process RESP3 push notifications and
222222
// route them to registered handlers.
223223
//
224-
// default: false
224+
// For RESP3 connections (Protocol: 3), push notifications are automatically enabled.
225+
// To disable push notifications for RESP3, use Protocol: 2 instead.
226+
// For RESP2 connections, push notifications are not available.
227+
//
228+
// default: automatically enabled for RESP3, disabled for RESP2
225229
PushNotifications bool
226230

227231
// PushNotificationProcessor is the processor for handling push notifications.

push_notifications.go

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@ func (f PushNotificationHandlerFunc) HandlePushNotification(ctx context.Context,
2828
type PushNotificationRegistry struct {
2929
mu sync.RWMutex
3030
handlers map[string]PushNotificationHandler // command -> single handler
31-
global []PushNotificationHandler // global handlers for all notifications
3231
}
3332

3433
// NewPushNotificationRegistry creates a new push notification registry.
3534
func NewPushNotificationRegistry() *PushNotificationRegistry {
3635
return &PushNotificationRegistry{
3736
handlers: make(map[string]PushNotificationHandler),
38-
global: make([]PushNotificationHandler, 0),
3937
}
4038
}
4139

@@ -52,14 +50,6 @@ func (r *PushNotificationRegistry) RegisterHandler(command string, handler PushN
5250
return nil
5351
}
5452

55-
// RegisterGlobalHandler registers a handler that will receive all push notifications.
56-
func (r *PushNotificationRegistry) RegisterGlobalHandler(handler PushNotificationHandler) {
57-
r.mu.Lock()
58-
defer r.mu.Unlock()
59-
60-
r.global = append(r.global, handler)
61-
}
62-
6353
// UnregisterHandler removes the handler for a specific push notification command.
6454
func (r *PushNotificationRegistry) UnregisterHandler(command string) {
6555
r.mu.Lock()
@@ -68,7 +58,7 @@ func (r *PushNotificationRegistry) UnregisterHandler(command string) {
6858
delete(r.handlers, command)
6959
}
7060

71-
// HandleNotification processes a push notification by calling all registered handlers.
61+
// HandleNotification processes a push notification by calling the registered handler.
7262
func (r *PushNotificationRegistry) HandleNotification(ctx context.Context, notification []interface{}) bool {
7363
if len(notification) == 0 {
7464
return false
@@ -83,23 +73,12 @@ func (r *PushNotificationRegistry) HandleNotification(ctx context.Context, notif
8373
r.mu.RLock()
8474
defer r.mu.RUnlock()
8575

86-
handled := false
87-
88-
// Call global handlers first
89-
for _, handler := range r.global {
90-
if handler.HandlePushNotification(ctx, notification) {
91-
handled = true
92-
}
93-
}
94-
9576
// Call specific handler
9677
if handler, exists := r.handlers[command]; exists {
97-
if handler.HandlePushNotification(ctx, notification) {
98-
handled = true
99-
}
78+
return handler.HandlePushNotification(ctx, notification)
10079
}
10180

102-
return handled
81+
return false
10382
}
10483

10584
// GetRegisteredCommands returns a list of commands that have registered handlers.
@@ -114,12 +93,12 @@ func (r *PushNotificationRegistry) GetRegisteredCommands() []string {
11493
return commands
11594
}
11695

117-
// HasHandlers returns true if there are any handlers registered (global or specific).
96+
// HasHandlers returns true if there are any handlers registered.
11897
func (r *PushNotificationRegistry) HasHandlers() bool {
11998
r.mu.RLock()
12099
defer r.mu.RUnlock()
121100

122-
return len(r.global) > 0 || len(r.handlers) > 0
101+
return len(r.handlers) > 0
123102
}
124103

125104
// PushNotificationProcessor handles the processing of push notifications from Redis.
@@ -206,22 +185,12 @@ func (p *PushNotificationProcessor) RegisterHandler(command string, handler Push
206185
return p.registry.RegisterHandler(command, handler)
207186
}
208187

209-
// RegisterGlobalHandler is a convenience method to register a global handler.
210-
func (p *PushNotificationProcessor) RegisterGlobalHandler(handler PushNotificationHandler) {
211-
p.registry.RegisterGlobalHandler(handler)
212-
}
213-
214188
// RegisterHandlerFunc is a convenience method to register a function as a handler.
215189
// Returns an error if a handler is already registered for this command.
216190
func (p *PushNotificationProcessor) RegisterHandlerFunc(command string, handlerFunc func(ctx context.Context, notification []interface{}) bool) error {
217191
return p.registry.RegisterHandler(command, PushNotificationHandlerFunc(handlerFunc))
218192
}
219193

220-
// RegisterGlobalHandlerFunc is a convenience method to register a function as a global handler.
221-
func (p *PushNotificationProcessor) RegisterGlobalHandlerFunc(handlerFunc func(ctx context.Context, notification []interface{}) bool) {
222-
p.registry.RegisterGlobalHandler(PushNotificationHandlerFunc(handlerFunc))
223-
}
224-
225194
// Common push notification commands
226195
const (
227196
// Redis Cluster notifications

0 commit comments

Comments
 (0)