public void OnPeriodicWorkException(IPeriodicWork failedWork, Exception ex, ref IPeriodicWorkExceptionHandler.Feedback feedback) { _logger.LogCritical("An unhandled exception has been raised in the block validation loop."); feedback.IsCritical = true; feedback.ContinueExecution = false; feedback.Message = "Without block validation loop, it's impossible to advance in consensus. A node restart is required to fix the problem."; }
public void OnPeriodicWorkException(IPeriodicWork failedWork, Exception ex, ref IPeriodicWorkExceptionHandler.Feedback feedback) { if (failedWork == connectionLoop) { logger.LogCritical(ex, "Connector {Connector} failure, it has been stopped, node may have connection problems.", GetType().Name); feedback.ContinueExecution = false; feedback.IsCritical = true; feedback.Message = "Without Connector loop no new connection can be established, restart the node to fix the problem."; return; } feedback.ContinueExecution = true; }
public void OnPeriodicWorkException(IPeriodicWork failedWork, Exception ex, ref IPeriodicWorkExceptionHandler.Feedback feedback) { string?disconnectionReason = failedWork switch { IPeriodicWork work when work == _headerSyncLoop => "Peer header syncing loop had failures.", _ => null }; if (disconnectionReason != null) { feedback.ContinueExecution = false; PeerContext.Disconnect(disconnectionReason); } }
private async Task StartInternalAsync(string label, IPeriodicWork.WorkAsync work, Func <TimeSpan> interval, CancellationToken cancellation) { if (_isRunning) { _logger.LogError("PeriodicWork {PeriodicWorkId} is already running.", Id); ThrowHelper.ThrowInvalidOperationException("Cannot start a periodic work that's already running."); return; } _label = label; Interlocked.Exchange(ref _exceptionsCount, 0); _periodicWorkTracker.StartTracking(this); using (_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellation)) { CancellationToken token = _cancellationTokenSource.Token; _logger.LogDebug("PeriodicWork {PeriodicWorkId} is starting.", Id); _isRunning = true; while (!token.IsCancellationRequested) { try { await work(token).WithCancellationAsync(token).ConfigureAwait(false); await Task.Delay(interval()).WithCancellationAsync(token).ConfigureAwait(false); } catch (OperationCanceledException) { _logger.LogDebug("PeriodicWork {PeriodicWorkId} aborted.", Id); break; } catch (Exception ex) { _lastException = ex; Interlocked.Increment(ref _exceptionsCount); var feedback = new IPeriodicWorkExceptionHandler.Feedback(!_stopOnException, false, null); _exceptionHandler?.OnPeriodicWorkException(this, ex, ref feedback); if (!feedback.ContinueExecution) { _logger.LogDebug("PeriodicWork {PeriodicWorkId} terminated because of {PeriodicWorkException}.", Id, ex); _isRunning = false; if (feedback.IsCritical) { _eventBus.Publish(new PeriodicWorkCriticallyStopped(_label, Id, _lastException, feedback.Message)); } return; } } } _isRunning = false; if (ExceptionsCount == 0) { _logger.LogDebug("PeriodicWork {PeriodicWorkId} terminated without errors.", Id); } else { _logger.LogDebug("PeriodicWork {PeriodicWorkId} terminated with {PeriodicWorkErrors} errors.", Id, ExceptionsCount); } } _periodicWorkTracker.StopTracking(this); }