diff --git a/src/Foundatio/Queues/QueueBase.cs b/src/Foundatio/Queues/QueueBase.cs index 2231b429..07f53e8f 100644 --- a/src/Foundatio/Queues/QueueBase.cs +++ b/src/Foundatio/Queues/QueueBase.cs @@ -69,7 +69,7 @@ protected QueueBase(TOptions options) : base(options?.TimeProvider, options?.Log { return (0, 0, 0); } - }); + }, _logger); _countGauge = FoundatioDiagnostics.Meter.CreateObservableGauge(GetFullMetricName("count"), () => new Measurement(queueMetricValues.GetValue1()), description: "Number of items in the queue"); _workingGauge = FoundatioDiagnostics.Meter.CreateObservableGauge(GetFullMetricName("working"), () => new Measurement(queueMetricValues.GetValue2()), description: "Number of items currently being processed"); diff --git a/src/Foundatio/Utility/InstrumentsValues.cs b/src/Foundatio/Utility/InstrumentsValues.cs index 922fb2ec..f9d9e128 100644 --- a/src/Foundatio/Utility/InstrumentsValues.cs +++ b/src/Foundatio/Utility/InstrumentsValues.cs @@ -1,4 +1,6 @@ using System; +using System.Threading; +using Microsoft.Extensions.Logging; namespace Foundatio.Utility; @@ -7,58 +9,57 @@ public class InstrumentsValues where T2 : struct where T3 : struct { + private readonly object _lock = new(); + private int _readCount; + private bool _valuesUpdating; + private readonly AutoResetEvent _valuesUpdatingEvent = new(false); private T1? _value1; private T2? _value2; private T3? _value3; - private Func<(T1, T2, T3)> UpdateValues { get; set; } + private readonly Func<(T1, T2, T3)> _readValuesFunc; + private readonly ILogger _logger; - public InstrumentsValues(Func<(T1, T2, T3)> readValues) + public InstrumentsValues(Func<(T1, T2, T3)> readValuesFunc, ILogger logger) { - _value1 = null; - _value2 = null; - _value3 = null; - - UpdateValues = readValues; + _readValuesFunc = readValuesFunc; + _logger = logger; } - public T1 GetValue1() + private void EnsureValues() { - if (!_value1.HasValue) - (_value1, _value2, _value3) = UpdateValues(); + lock (_lock) + { + if (_readCount == 0) { + _logger.LogDebug("Getting values"); + (_value1, _value2, _value3) = _readValuesFunc(); + } - if (_value1 == null) - return default; + // get values every 3 reads + if (_readCount == 2) + _readCount = 0; + else + _readCount++; + } + } - T1 value = _value1.Value; - _value1 = null; - return value; + public T1 GetValue1() + { + EnsureValues(); + return _value1 ?? default; } public T2 GetValue2() { - if (!_value2.HasValue) - (_value1, _value2, _value3) = UpdateValues(); - - if (_value2 == null) - return default; - - T2 value = _value2.Value; - _value2 = null; - return value; + EnsureValues(); + return _value2 ?? default; } public T3 GetValue3() { - if (!_value3.HasValue) - (_value1, _value2, _value3) = UpdateValues(); - - if (_value3 == null) - return default; + EnsureValues(); - T3 value = _value3.Value; - _value3 = null; - return value; + return _value3 ?? default; } }