private async Task ElectionTimeoutTask(CancellationToken cancelationToken) { var timeout = RandomElectionTimeout(); Console.WriteLine($" timeout{timeout} node {Id.N} temen{_currentTerm.N}"); // loop, sleeping for ~ the broadcast (timeout) time. If // we have gone too long without while (!_timeoutCancellationSource.IsCancellationRequested) { var sinceHeartbeat = DateTime.Now - _lastHeartbeat; if (sinceHeartbeat > timeout) { ResetElectionTimer(); Supervised.Run(function: TransitionToCandidate); continue; } try { var sinceHeartbeat2 = DateTime.Now - _lastHeartbeat; await Task.Delay(timeout - sinceHeartbeat2, cancelationToken); } catch (TaskCanceledException) { // cancelled or disposed means we are no longer a // follower, so end this task return; } catch (ObjectDisposedException) { return; } } }
private Task TransitionToFollower() { if (_state != State.Follower) { _state = State.Follower; _timeoutCancellationSource = new CancellationTokenSource(); Supervised.Run(() => ElectionTimeoutTask(_timeoutCancellationSource.Token)); } return(Task.CompletedTask); }