@@ -2,6 +2,7 @@ package redis
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"sync"
6
7
7
8
"github.com/redis/go-redis/v9/internal"
@@ -26,27 +27,29 @@ func (f PushNotificationHandlerFunc) HandlePushNotification(ctx context.Context,
26
27
// PushNotificationRegistry manages handlers for different types of push notifications.
27
28
type PushNotificationRegistry struct {
28
29
mu sync.RWMutex
29
- handlers map [string ][] PushNotificationHandler // command -> handlers
30
- global []PushNotificationHandler // global handlers for all notifications
30
+ handlers map [string ]PushNotificationHandler // command -> single handler
31
+ global []PushNotificationHandler // global handlers for all notifications
31
32
}
32
33
33
34
// NewPushNotificationRegistry creates a new push notification registry.
34
35
func NewPushNotificationRegistry () * PushNotificationRegistry {
35
36
return & PushNotificationRegistry {
36
- handlers : make (map [string ][] PushNotificationHandler ),
37
+ handlers : make (map [string ]PushNotificationHandler ),
37
38
global : make ([]PushNotificationHandler , 0 ),
38
39
}
39
40
}
40
41
41
42
// RegisterHandler registers a handler for a specific push notification command.
42
- func (r * PushNotificationRegistry ) RegisterHandler (command string , handler PushNotificationHandler ) {
43
+ // Returns an error if a handler is already registered for this command.
44
+ func (r * PushNotificationRegistry ) RegisterHandler (command string , handler PushNotificationHandler ) error {
43
45
r .mu .Lock ()
44
46
defer r .mu .Unlock ()
45
47
46
- if r .handlers [command ] == nil {
47
- r . handlers [ command ] = make ([] PushNotificationHandler , 0 )
48
+ if _ , exists := r .handlers [command ]; exists {
49
+ return fmt . Errorf ( "handler already registered for command: %s" , command )
48
50
}
49
- r .handlers [command ] = append (r .handlers [command ], handler )
51
+ r .handlers [command ] = handler
52
+ return nil
50
53
}
51
54
52
55
// RegisterGlobalHandler registers a handler that will receive all push notifications.
@@ -57,19 +60,12 @@ func (r *PushNotificationRegistry) RegisterGlobalHandler(handler PushNotificatio
57
60
r .global = append (r .global , handler )
58
61
}
59
62
60
- // UnregisterHandler removes a handler for a specific command.
61
- func (r * PushNotificationRegistry ) UnregisterHandler (command string , handler PushNotificationHandler ) {
63
+ // UnregisterHandler removes the handler for a specific push notification command.
64
+ func (r * PushNotificationRegistry ) UnregisterHandler (command string ) {
62
65
r .mu .Lock ()
63
66
defer r .mu .Unlock ()
64
67
65
- handlers := r .handlers [command ]
66
- for i , h := range handlers {
67
- // Compare function pointers (this is a simplified approach)
68
- if & h == & handler {
69
- r .handlers [command ] = append (handlers [:i ], handlers [i + 1 :]... )
70
- break
71
- }
72
- }
68
+ delete (r .handlers , command )
73
69
}
74
70
75
71
// HandleNotification processes a push notification by calling all registered handlers.
@@ -96,12 +92,10 @@ func (r *PushNotificationRegistry) HandleNotification(ctx context.Context, notif
96
92
}
97
93
}
98
94
99
- // Call specific handlers
100
- if handlers , exists := r .handlers [command ]; exists {
101
- for _ , handler := range handlers {
102
- if handler .HandlePushNotification (ctx , notification ) {
103
- handled = true
104
- }
95
+ // Call specific handler
96
+ if handler , exists := r .handlers [command ]; exists {
97
+ if handler .HandlePushNotification (ctx , notification ) {
98
+ handled = true
105
99
}
106
100
}
107
101
@@ -207,8 +201,9 @@ func (p *PushNotificationProcessor) ProcessPendingNotifications(ctx context.Cont
207
201
}
208
202
209
203
// RegisterHandler is a convenience method to register a handler for a specific command.
210
- func (p * PushNotificationProcessor ) RegisterHandler (command string , handler PushNotificationHandler ) {
211
- p .registry .RegisterHandler (command , handler )
204
+ // Returns an error if a handler is already registered for this command.
205
+ func (p * PushNotificationProcessor ) RegisterHandler (command string , handler PushNotificationHandler ) error {
206
+ return p .registry .RegisterHandler (command , handler )
212
207
}
213
208
214
209
// RegisterGlobalHandler is a convenience method to register a global handler.
@@ -217,8 +212,9 @@ func (p *PushNotificationProcessor) RegisterGlobalHandler(handler PushNotificati
217
212
}
218
213
219
214
// RegisterHandlerFunc is a convenience method to register a function as a handler.
220
- func (p * PushNotificationProcessor ) RegisterHandlerFunc (command string , handlerFunc func (ctx context.Context , notification []interface {}) bool ) {
221
- p .registry .RegisterHandler (command , PushNotificationHandlerFunc (handlerFunc ))
215
+ // Returns an error if a handler is already registered for this command.
216
+ func (p * PushNotificationProcessor ) RegisterHandlerFunc (command string , handlerFunc func (ctx context.Context , notification []interface {}) bool ) error {
217
+ return p .registry .RegisterHandler (command , PushNotificationHandlerFunc (handlerFunc ))
222
218
}
223
219
224
220
// RegisterGlobalHandlerFunc is a convenience method to register a function as a global handler.
0 commit comments