6
6
"os"
7
7
"path/filepath"
8
8
"runtime"
9
+ "sync"
9
10
10
11
"github.com/obot-platform/nah/pkg/backend"
11
12
"github.com/obot-platform/nah/pkg/leader"
@@ -21,10 +22,9 @@ type Router struct {
21
22
OnErrorHandler ErrorHandler
22
23
handlers * HandlerSet
23
24
electionConfig * leader.ElectionConfig
24
- hasHealthz bool
25
+ startLock sync. Mutex
25
26
postStarts []func (context.Context , kclient.Client )
26
27
signalStopped chan struct {}
27
- cancel func ()
28
28
}
29
29
30
30
// New returns a new *Router with given HandlerSet and ElectionConfig. Passing a nil ElectionConfig is valid and results
@@ -41,7 +41,6 @@ func New(handlerSet *HandlerSet, electionConfig *leader.ElectionConfig, healthzP
41
41
42
42
if healthzPort > 0 {
43
43
setPort (healthzPort )
44
- r .hasHealthz = true
45
44
}
46
45
47
46
r .RouteBuilder .router = r
@@ -187,44 +186,43 @@ func (r RouteBuilder) Handler(h Handler) {
187
186
}
188
187
189
188
func (r * Router ) Start (ctx context.Context ) error {
190
- if r .cancel != nil {
191
- return fmt .Errorf ("router already started" )
192
- }
193
-
194
189
id , err := os .Hostname ()
195
190
if err != nil {
196
191
return err
197
192
}
198
193
199
- if r .hasHealthz {
200
- startHealthz (ctx )
201
- }
194
+ startHealthz (ctx )
202
195
203
196
r .handlers .onError = r .OnErrorHandler
204
197
205
- ctx , r .cancel = context .WithCancel (ctx )
206
-
207
198
// It's OK to start the electionConfig even if it's nil.
208
199
return r .electionConfig .Run (ctx , id , r .startHandlers , func (leader string ) {
200
+ if id == leader {
201
+ return
202
+ }
203
+
204
+ r .startLock .Lock ()
205
+ defer r .startLock .Unlock ()
206
+
207
+ setHealthy (r .name , false )
208
+ defer setHealthy (r .name , true )
209
209
// I am not the leader, so I am healthy when my cache is ready.
210
210
if err := r .handlers .Preload (ctx ); err != nil {
211
211
// Failed to preload caches, panic
212
212
log .Fatalf ("failed to preload caches: %v" , err )
213
213
}
214
- if r .hasHealthz {
215
- setHealthy (r .name , id != leader )
216
- }
217
214
}, r .signalStopped )
218
215
}
219
216
220
217
// startHandlers gets called when we become the leader or if there is no leader election.
221
218
func (r * Router ) startHandlers (ctx context.Context ) error {
219
+ r .startLock .Lock ()
220
+ defer r .startLock .Unlock ()
221
+
222
222
var err error
223
223
// This is the leader now, so not ready until the controller is started and caches are ready.
224
- if r .hasHealthz {
225
- setHealthy (r .name , false )
226
- defer setHealthy (r .name , err == nil )
227
- }
224
+ setHealthy (r .name , false )
225
+ defer setHealthy (r .name , err == nil )
228
226
229
227
if err = r .handlers .Start (ctx ); err != nil {
230
228
return err
0 commit comments