audit, advisories and doctors/setup work
This commit is contained in:
@@ -13,6 +13,7 @@ builder.Configuration
|
||||
.AddEnvironmentVariables(prefix: "ADVISORYAI__");
|
||||
|
||||
builder.Services.AddAdvisoryAiCore(builder.Configuration);
|
||||
builder.Services.AddSingleton<IAdvisoryJitterSource, DefaultAdvisoryJitterSource>();
|
||||
builder.Services.AddHostedService<AdvisoryTaskWorker>();
|
||||
|
||||
var host = builder.Build();
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("StellaOps.AdvisoryAI.Tests")]
|
||||
@@ -10,7 +10,7 @@ using StellaOps.AdvisoryAI.Execution;
|
||||
|
||||
namespace StellaOps.AdvisoryAI.Worker.Services;
|
||||
|
||||
internal sealed class AdvisoryTaskWorker : BackgroundService
|
||||
public class AdvisoryTaskWorker : BackgroundService
|
||||
{
|
||||
private const int MaxRetryDelaySeconds = 60;
|
||||
private const int BaseRetryDelaySeconds = 2;
|
||||
@@ -22,7 +22,7 @@ internal sealed class AdvisoryTaskWorker : BackgroundService
|
||||
private readonly AdvisoryPipelineMetrics _metrics;
|
||||
private readonly IAdvisoryPipelineExecutor _executor;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private readonly Func<double> _jitterSource;
|
||||
private readonly IAdvisoryJitterSource _jitterSource;
|
||||
private readonly ILogger<AdvisoryTaskWorker> _logger;
|
||||
private int _consecutiveErrors;
|
||||
|
||||
@@ -34,7 +34,7 @@ internal sealed class AdvisoryTaskWorker : BackgroundService
|
||||
IAdvisoryPipelineExecutor executor,
|
||||
TimeProvider timeProvider,
|
||||
ILogger<AdvisoryTaskWorker> logger,
|
||||
Func<double>? jitterSource = null)
|
||||
IAdvisoryJitterSource jitterSource)
|
||||
{
|
||||
_queue = queue ?? throw new ArgumentNullException(nameof(queue));
|
||||
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
|
||||
@@ -42,7 +42,7 @@ internal sealed class AdvisoryTaskWorker : BackgroundService
|
||||
_metrics = metrics ?? throw new ArgumentNullException(nameof(metrics));
|
||||
_executor = executor ?? throw new ArgumentNullException(nameof(executor));
|
||||
_timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
|
||||
_jitterSource = jitterSource ?? Random.Shared.NextDouble;
|
||||
_jitterSource = jitterSource ?? throw new ArgumentNullException(nameof(jitterSource));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ internal sealed class AdvisoryTaskWorker : BackgroundService
|
||||
var backoff = Math.Min(BaseRetryDelaySeconds * Math.Pow(2, errorCount - 1), MaxRetryDelaySeconds);
|
||||
|
||||
// Add jitter (+/- JitterFactor percent) using injectable source for testability
|
||||
var jitter = backoff * JitterFactor * (2 * _jitterSource() - 1);
|
||||
var jitter = backoff * JitterFactor * (2 * _jitterSource.NextDouble() - 1);
|
||||
|
||||
return Math.Max(BaseRetryDelaySeconds, backoff + jitter);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace StellaOps.AdvisoryAI.Worker.Services;
|
||||
|
||||
public interface IAdvisoryJitterSource
|
||||
{
|
||||
double NextDouble();
|
||||
}
|
||||
|
||||
internal sealed class DefaultAdvisoryJitterSource : IAdvisoryJitterSource
|
||||
{
|
||||
private readonly Random _random;
|
||||
private readonly object _lock = new();
|
||||
|
||||
public DefaultAdvisoryJitterSource(TimeProvider timeProvider)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(timeProvider);
|
||||
var seed = unchecked((int)timeProvider.GetUtcNow().ToUnixTimeMilliseconds());
|
||||
_random = new Random(seed);
|
||||
}
|
||||
|
||||
public double NextDouble()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _random.NextDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user