From 02fda85ee0d86ebca8fa1b12cb329426e0cd343d Mon Sep 17 00:00:00 2001 From: scooletz Date: Mon, 2 Sep 2024 10:49:45 +0200 Subject: [PATCH] controller updated with the new signalling --- .../Metrics/MetricsController.cs | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs b/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs index ef544c3af8e..e73988c043e 100644 --- a/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs +++ b/src/Nethermind/Nethermind.Monitoring/Metrics/MetricsController.cs @@ -22,12 +22,18 @@ namespace Nethermind.Monitoring.Metrics { + /// + /// The metrics controller handles gathering metrics every . + /// Additionally, it allows forcing an update by calling that makes the wait interrupted and reporting executed immediately. + /// To do not flood the endpoint, is configured so that report happens with a gap that is at least that big. + /// public partial class MetricsController : IMetricsController { private readonly int _intervalSeconds; private readonly int _minIntervalSeconds; private CancellationTokenSource _cts; - private readonly SemaphoreSlim _wait = new(0); + private TaskCompletionSource _wait = new(); + private readonly object _waitLock = new(); private readonly Dictionary)[]> _membersCache = new(); private readonly Dictionary _dictionaryCache = new(); private readonly HashSet _metricTypes = new(); @@ -194,7 +200,6 @@ public MetricsController(IMetricsConfig metricsConfig) { _intervalSeconds = metricsConfig.IntervalSeconds == 0 ? 5 : metricsConfig.IntervalSeconds; _minIntervalSeconds = metricsConfig.MinimalIntervalSeconds == 0 ? 2 : metricsConfig.MinimalIntervalSeconds; - _useCounters = metricsConfig.CountersEnabled; } @@ -213,14 +218,20 @@ async Task RunLoop(CancellationToken ct) { bool forced = false; + Task wait = GetForceUpdateWait(); + try { - forced = await _wait.WaitAsync(waitTime, ct); + + Task finished = await Task.WhenAny(wait, Task.Delay(waitTime, ct)); + forced = finished == wait; } catch (OperationCanceledException) { } + ResetForceUpdate(); + UpdateMetrics(); if (forced && onForced != null) @@ -244,7 +255,32 @@ async Task RunLoop(CancellationToken ct) } } - public void ForceUpdate() => _wait.Release(); + public void ForceUpdate() + { + lock (_waitLock) + { + _wait.TrySetResult(); + } + } + + private Task GetForceUpdateWait() + { + lock (_waitLock) + { + return _wait.Task; + } + } + + private void ResetForceUpdate() + { + lock (_waitLock) + { + if (_wait.Task.IsCompleted) + { + _wait = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + } + } + } public void StopUpdating() => _cts.Cancel();