Files
git.stella-ops.org/src/JobEngine/StellaOps.Scheduler.WebService/EventWebhooks/WebhookRateLimiterServiceCollectionExtensions.cs
master 70cbfcee72 feat(scheduler): postgres + redis webhook rate limiter runtime
Sprint SPRINT_20260417_019_JobEngine_truthful_webhook_rate_limiter_runtime.

NoOpWebhookRateLimiter + RedisWebhookRateLimiter, service-collection
wiring, WebhookRateLimiterRuntimeTests, SCHED-WEB-16-104-WEBHOOKS doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 14:41:42 +03:00

68 lines
2.6 KiB
C#

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using StellaOps.Scheduler.Queue;
using StellaOps.Scheduler.WebService.GraphJobs.Events;
using StellaOps.Scheduler.WebService.Options;
using System;
namespace StellaOps.Scheduler.WebService.EventWebhooks;
internal static class WebhookRateLimiterServiceCollectionExtensions
{
public static IServiceCollection AddSchedulerWebhookRateLimiter(
this IServiceCollection services,
IConfiguration configuration,
IHostEnvironment environment)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(configuration);
ArgumentNullException.ThrowIfNull(environment);
services.RemoveAll<IWebhookRateLimiter>();
if (environment.IsEnvironment("Testing"))
{
services.AddSingleton<IWebhookRateLimiter, InMemoryWebhookRateLimiter>();
return services;
}
var eventsOptions = new SchedulerEventsOptions();
configuration.GetSection("Scheduler:Events").Bind(eventsOptions);
eventsOptions.Webhooks ??= new SchedulerInboundWebhooksOptions();
eventsOptions.Webhooks.Conselier ??= SchedulerWebhookOptions.CreateDefault("conselier");
eventsOptions.Webhooks.Excitor ??= SchedulerWebhookOptions.CreateDefault("excitor");
if (!eventsOptions.Webhooks.Conselier.Enabled && !eventsOptions.Webhooks.Excitor.Enabled)
{
services.AddSingleton<IWebhookRateLimiter, NoOpWebhookRateLimiter>();
return services;
}
var queueOptions = new SchedulerQueueOptions();
configuration.GetSection("scheduler:queue").Bind(queueOptions);
if (queueOptions.Kind != SchedulerQueueTransportKind.Redis || string.IsNullOrWhiteSpace(queueOptions.Redis.ConnectionString))
{
throw new InvalidOperationException(
"Scheduler inbound webhooks require scheduler:queue Redis connection outside the Testing environment.");
}
var redisOptions = new SchedulerRedisQueueOptions
{
ConnectionString = queueOptions.Redis.ConnectionString,
Database = queueOptions.Redis.Database,
InitializationTimeout = queueOptions.Redis.InitializationTimeout
};
services.AddSingleton<IWebhookRateLimiter>(sp =>
new RedisWebhookRateLimiter(
redisOptions,
sp.GetRequiredService<IRedisConnectionFactory>(),
sp.GetService<TimeProvider>()));
return services;
}
}