@@ -34,7 +34,7 @@ func main() {
3434
3535 configBytes = []byte (os .ExpandEnv (string (configBytes )))
3636
37- cfg , err := setup .ParseConfigFromBites (configBytes )
37+ cfg , err := setup .ParseConfigFromBytes (configBytes )
3838 if err != nil {
3939 log .Fatal ().Msg (err .Error ())
4040 }
@@ -64,6 +64,8 @@ func main() {
6464
6565 cfg .SetDefaults ()
6666
67+ log .Info ().Msgf ("Starting with config: %#v" , cfg )
68+
6769 if err := cfg .Validate (); err != nil {
6870 log .Fatal ().Err (err ).Msg ("config validation failed" )
6971 }
@@ -91,45 +93,61 @@ func main() {
9193
9294 w := kube .NewEventWatcher (kubecfg , cfg .Namespace , cfg .MaxEventAgeSeconds , metricsStore , onEvent , cfg .OmitLookup , cfg .CacheSize )
9395
94- ctx , cancel := context .WithCancel (context .Background ())
95- leaderLost := make (chan bool )
96+ ctx , cancel := signal .NotifyContext (context .Background (), syscall .SIGINT , syscall .SIGTERM )
97+ defer cancel ()
98+
9699 if cfg .LeaderElection .Enabled {
100+ var wasLeader bool
101+ log .Info ().Msg ("leader election enabled" )
102+
103+ onStoppedLeading := func (ctx context.Context ) {
104+ select {
105+ case <- ctx .Done ():
106+ log .Info ().Msg ("Context was cancelled, stopping leader election loop" )
107+ default :
108+ log .Info ().Msg ("Lost the leader lease, stopping leader election loop" )
109+ }
110+ }
111+
97112 l , err := kube .NewLeaderElector (cfg .LeaderElection .LeaderElectionID , kubecfg ,
113+ // this method gets called when this instance becomes the leader
98114 func (_ context.Context ) {
99- log .Info ().Msg ("leader election got" )
115+ wasLeader = true
116+ log .Info ().Msg ("leader election won" )
100117 w .Start ()
101118 },
119+ // this method gets called when the leader election loop is closed
120+ // either due to context cancellation or due to losing the leader lease
102121 func () {
103- log .Error ().Msg ("leader election lost" )
104- leaderLost <- true
122+ onStoppedLeading (ctx )
123+ },
124+ func (identity string ) {
125+ log .Info ().Msg ("new leader observed: " + identity )
105126 },
106127 )
107128 if err != nil {
108129 log .Fatal ().Err (err ).Msg ("create leaderelector failed" )
109130 }
110- go l .Run (ctx )
131+
132+ // Run returns if either the context is canceled or client stopped holding the leader lease
133+ l .Run (ctx )
134+
135+ // We get here either because we lost the leader lease or the context was canceled.
136+ // In either case we want to stop the event watcher and exit.
137+ // However, if we were the leader, we wait leaseDuration seconds before stopping
138+ // so that we don't lose events until the next leader is elected. The new leader
139+ // will only be elected after leaseDuration seconds.
140+ if wasLeader {
141+ log .Info ().Msgf ("waiting leaseDuration seconds before stopping: %s" , kube .GetLeaseDuration ())
142+ time .Sleep (kube .GetLeaseDuration ())
143+ }
111144 } else {
145+ log .Info ().Msg ("leader election disabled" )
112146 w .Start ()
147+ <- ctx .Done ()
113148 }
114149
115- c := make (chan os.Signal , 1 )
116- signal .Notify (c , syscall .SIGINT , syscall .SIGTERM )
117-
118- gracefulExit := func () {
119- defer close (c )
120- defer close (leaderLost )
121- cancel ()
122- w .Stop ()
123- engine .Stop ()
124- log .Info ().Msg ("Exiting" )
125- }
126-
127- select {
128- case sig := <- c :
129- log .Info ().Str ("signal" , sig .String ()).Msg ("Received signal to exit" )
130- gracefulExit ()
131- case <- leaderLost :
132- log .Warn ().Msg ("Leader election lost" )
133- gracefulExit ()
134- }
150+ log .Info ().Msg ("Received signal to exit. Stopping." )
151+ w .Stop ()
152+ engine .Stop ()
135153}
0 commit comments