@@ -53,6 +53,7 @@ type Manager struct {
53
53
success , failure chan dispatchResult
54
54
55
55
mu sync.Mutex // Protects following.
56
+ closed bool
56
57
notifier * notifier
57
58
58
59
runOnce sync.Once
@@ -134,6 +135,8 @@ func (m *Manager) WithHandlers(reg map[database.NotificationMethod]Handler) {
134
135
m .handlers = reg
135
136
}
136
137
138
+ var ErrManagerAlreadyClosed = xerrors .New ("manager already closed" )
139
+
137
140
// Run initiates the control loop in the background, which spawns a given number of notifier goroutines.
138
141
// Manager requires system-level permissions to interact with the store.
139
142
// Run is only intended to be run once.
@@ -145,7 +148,11 @@ func (m *Manager) Run(ctx context.Context) {
145
148
go func () {
146
149
err := m .loop (ctx )
147
150
if err != nil {
148
- m .log .Error (ctx , "notification manager stopped with error" , slog .Error (err ))
151
+ if xerrors .Is (err , ErrManagerAlreadyClosed ) {
152
+ m .log .Warn (ctx , "notification manager stopped with error" , slog .Error (err ))
153
+ } else {
154
+ m .log .Error (ctx , "notification manager stopped with error" , slog .Error (err ))
155
+ }
149
156
}
150
157
}()
151
158
})
@@ -160,6 +167,11 @@ func (m *Manager) loop(ctx context.Context) error {
160
167
}()
161
168
162
169
m .mu .Lock ()
170
+ if m .closed {
171
+ m .mu .Unlock ()
172
+ return ErrManagerAlreadyClosed
173
+ }
174
+
163
175
var eg errgroup.Group
164
176
165
177
m .notifier = newNotifier (ctx , m .cfg , uuid .New (), m .log , m .store , m .handlers , m .helpers , m .metrics , m .clock )
@@ -348,11 +360,10 @@ func (m *Manager) Stop(ctx context.Context) error {
348
360
m .mu .Lock ()
349
361
defer m .mu .Unlock ()
350
362
351
- select {
352
- case <- m .stop :
363
+ if m .closed {
353
364
return nil
354
- default :
355
365
}
366
+ m .closed = true
356
367
357
368
m .log .Debug (context .Background (), "graceful stop requested" )
358
369
0 commit comments