audit, advisories and doctors/setup work

This commit is contained in:
master
2026-01-13 18:53:39 +02:00
parent 9ca7cb183e
commit d7be6ba34b
811 changed files with 54242 additions and 4056 deletions

View File

@@ -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();

View File

@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("StellaOps.AdvisoryAI.Tests")]

View File

@@ -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);
}

View File

@@ -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();
}
}
}