using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Logging; using StellaOps.Scheduler.Queue.Nats; using StellaOps.Scheduler.Queue.Redis; namespace StellaOps.Scheduler.Queue; public static class SchedulerQueueServiceCollectionExtensions { public static IServiceCollection AddSchedulerQueues( this IServiceCollection services, IConfiguration configuration, string sectionName = "scheduler:queue") { ArgumentNullException.ThrowIfNull(services); ArgumentNullException.ThrowIfNull(configuration); var options = new SchedulerQueueOptions(); configuration.GetSection(sectionName).Bind(options); services.TryAddSingleton(TimeProvider.System); services.AddSingleton(options); services.AddSingleton(sp => { var loggerFactory = sp.GetRequiredService(); var timeProvider = sp.GetService() ?? TimeProvider.System; return options.Kind switch { SchedulerQueueTransportKind.Redis => new RedisSchedulerPlannerQueue( options, options.Redis, loggerFactory.CreateLogger(), timeProvider), SchedulerQueueTransportKind.Nats => new NatsSchedulerPlannerQueue( options, options.Nats, loggerFactory.CreateLogger(), timeProvider), _ => throw new InvalidOperationException($"Unsupported scheduler queue transport '{options.Kind}'.") }; }); services.AddSingleton(sp => { var loggerFactory = sp.GetRequiredService(); var timeProvider = sp.GetService() ?? TimeProvider.System; return options.Kind switch { SchedulerQueueTransportKind.Redis => new RedisSchedulerRunnerQueue( options, options.Redis, loggerFactory.CreateLogger(), timeProvider), SchedulerQueueTransportKind.Nats => new NatsSchedulerRunnerQueue( options, options.Nats, loggerFactory.CreateLogger(), timeProvider), _ => throw new InvalidOperationException($"Unsupported scheduler queue transport '{options.Kind}'.") }; }); services.AddSingleton(); return services; } public static IHealthChecksBuilder AddSchedulerQueueHealthCheck( this IHealthChecksBuilder builder) { ArgumentNullException.ThrowIfNull(builder); builder.Services.TryAddSingleton(); builder.AddCheck( name: "scheduler-queue", failureStatus: HealthStatus.Unhealthy, tags: new[] { "scheduler", "queue" }); return builder; } }