@@ -63,6 +63,7 @@ func (d *DynamicLeaderElection) Run(ctx context.Context) error {
6363 }()
6464
6565 startWorker := func (name string , workerFunc func (ctx context.Context ) error ) {
66+ workerCancel ()
6667 workerCtx , cancel := context .WithCancel (ctx )
6768 workerCancel = cancel
6869 wg .Add (1 )
@@ -89,12 +90,20 @@ func (d *DynamicLeaderElection) Run(ctx context.Context) error {
8990 d .logger .Info ().Msg ("Raft leader changed notification" )
9091 if becameLeader && ! isCurrentlyLeader { // new leader
9192 if isStarted {
93+ var synced bool
9294 d .logger .Info ().Msg ("became leader, stopping follower operations" )
9395 // wait for in flight raft msgs to land
94- time .Sleep (d .node .Config ().SendTimeout )
95- if ! runnable .IsSynced (d .node .GetState ()) {
96+ awaitSyncLoop:
97+ for end := time .Now ().Add (d .node .Config ().SendTimeout ); time .Now ().Before (end ); {
98+ if synced = runnable .IsSynced (d .node .GetState ()); synced {
99+ break awaitSyncLoop
100+ }
101+ time .Sleep (d .node .Config ().SendTimeout / 10 )
102+ }
103+ if ! synced && ! runnable .IsSynced (d .node .GetState ()) {
96104 d .logger .Info ().Msg ("became leader, but not synced. Pass on leadership" )
97105 if err := d .node .leadershipTransfer (); err != nil && ! errors .Is (err , raft .ErrNotLeader ) {
106+ // the leadership transfer can fail due to no suitable leader. Better stop than double sign on old state
98107 return err
99108 }
100109 continue
@@ -127,10 +136,12 @@ func (d *DynamicLeaderElection) Run(ctx context.Context) error {
127136 case <- ticker .C : // LeaderCh fires only when leader changes not on initial election
128137 if isStarted {
129138 ticker .Stop ()
139+ ticker .C = nil
130140 continue
131141 }
132142 if leaderID := d .node .leaderID (); leaderID != "" && leaderID != d .node .NodeID () {
133143 ticker .Stop ()
144+ ticker .C = nil
134145 d .logger .Info ().Msg ("starting follower operations" )
135146 isStarted = true
136147 var err error
0 commit comments