Files
AutopilotMonitor/src/Backend/AutopilotMonitor.Functions/Functions/Admin/SignalRQuotaTimerFunction.cs
T
Oliver Kieselbach 2d5f87140f chore: retarget SignalR quota watcher to Standard S1 limits + CI build hygiene
- SignalR quota watcher/health card: defaults 20/20k (Free tier) -> 1000/1M
  (Standard S1 x1 unit); settings renamed SignalRFreeTier* -> SignalRConnectionLimit/
  SignalRDailyMessageLimit (no Azure overrides were set); all operator-facing
  texts tier-neutral (connections 429 hard, message overage is billed not throttled)
- web: drop obsolete edge runtime from opengraph/twitter/apple-icon image routes
  (next/og runs on Node since 14; images now statically generated at build)
- web: update caniuse-lite browser db (silences 6-months-old Browserslist warning)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:38:15 +02:00

47 lines
1.9 KiB
C#

using System.Threading;
using System.Threading.Tasks;
using AutopilotMonitor.Functions.Services;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace AutopilotMonitor.Functions.Functions.Admin
{
/// <summary>
/// Timer-triggered watcher for the Azure SignalR plan limits (Standard S1
/// x1 unit: 1,000 concurrent connections / 1M messages per UTC day). Runs
/// every full hour and emits OpsEvents when the configured thresholds are
/// crossed so operators get a Telegram ping before clients start getting
/// 429'd or message overage is billed.
///
/// Separate from the 2h MaintenanceFunction: the SignalR limits can be
/// breached by a brief connection spike, so the cadence is tighter. Cost
/// impact is negligible (~720 extra executions/month, ~$0.04).
/// </summary>
public class SignalRQuotaTimerFunction
{
private readonly MaintenanceService _maintenanceService;
private readonly ILogger<SignalRQuotaTimerFunction> _logger;
public SignalRQuotaTimerFunction(
MaintenanceService maintenanceService,
ILogger<SignalRQuotaTimerFunction> logger)
{
_maintenanceService = maintenanceService;
_logger = logger;
}
/// <summary>
/// NCRONTAB "0 0 * * * *" - every hour on the minute. The watcher itself
/// is idempotent (one OpsEvent per EventType per UTC day) and skips
/// silently when SignalRResourceId is unset, so this trigger is safe to
/// run in environments without managed-identity wiring.
/// </summary>
[Function("SignalRQuotaTimer")]
public async Task Run([TimerTrigger("0 0 * * * *")] object timer, CancellationToken ct)
{
_logger.LogInformation("SignalR quota watcher fired");
await _maintenanceService.CheckSignalRQuotaAsync(ct);
}
}
}