The bug occurred because we had two layers of task::spawn() calls in the follower timeout logic. This in turn led to cancellation only affecting the outer layer, and not actually cancelling the control flow.
The overall effect was a lot of thrash in leader election because even with an established leader, runaway follower timeout code would start new elections.
This change also does a few minor cleanups:
Replace some static functions with member functions
Add timeouts to connect calls
Reuse follower timeout scheduling logic rather than duplicating it
The bug occurred because we had two layers of task::spawn() calls in the follower timeout logic. This in turn led to cancellation only affecting the outer layer, and not actually cancelling the control flow.
The overall effect was a lot of thrash in leader election because even with an established leader, runaway follower timeout code would start new elections.
This change also does a few minor cleanups: