private void Run(object obj) { try { try { Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; } catch (Exception e) { if (_engine.Log.IsInfoEnabled) { _engine.Log.Info($"{_debugName} was unable to set the thread priority, will continue with the same priority", e); } } using (this) { try { using (_engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context)) { NegotiateWithLeader(context, (LogLengthNegotiation)obj); } FollowerSteadyState(); } catch (Exception e) when(RachisConsensus.IsExpectedException(e)) { } catch (Exception e) { _debugRecorder.Record($"Sending error: {e}"); using (_engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context)) { _connection.Send(context, e); } if (_engine.Log.IsInfoEnabled) { _engine.Log.Info($"{ToString()}: Failed to talk to leader", e); } } } } catch (Exception e) when(RachisConsensus.IsExpectedException(e)) { } catch (Exception e) { if (_engine.Log.IsInfoEnabled) { _engine.Log.Info("Failed to dispose follower when talking to the leader: " + _engine.Tag, e); } } }
private async Task Concurrent_SendAppendEntriesPendingToLeaderAsync(CancellationTokenSource cts, long currentTerm, long lastLogIndex) { var timeoutPeriod = _engine.Timeout.TimeoutPeriod / 4; var timeToWait = TimeSpan.FromMilliseconds(timeoutPeriod); using (_engine.ContextPool.AllocateOperationContext(out JsonOperationContext timeoutCtx)) { while (cts.IsCancellationRequested == false) { try { timeoutCtx.Reset(); timeoutCtx.Renew(); await TimeoutManager.WaitFor(timeToWait, cts.Token); if (cts.IsCancellationRequested) { break; } _engine.Timeout.Defer(_connection.Source); _connection.Send(timeoutCtx, new AppendEntriesResponse { Pending = true, Success = false, CurrentTerm = currentTerm, LastLogIndex = lastLogIndex }); } catch (TimeoutException) { break; } catch (Exception e) when(RachisConsensus.IsExpectedException(e)) { break; } } } }