using Microsoft.Extensions.Hosting; namespace WxAgent.Service; public interface IAgentEventSource { IAsyncEnumerable ListenAsync(CancellationToken cancellationToken); } public sealed class EventPump(IAgentBackend backend, EventHub hub, ServiceOptions options) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { if (backend is not IAgentEventSource source || backend.Capabilities.All(c => c.Operation != "listener-events" || !c.Enabled)) return; while (!stoppingToken.IsCancellationRequested) { try { await foreach (var item in source.ListenAsync(stoppingToken)) { foreach (var credential in options.ReadCredentials()) if (credential.AccountIds.Length == 0 || credential.AccountIds.Contains(item.AccountId, StringComparer.Ordinal)) hub.Publish(credential.PrincipalId, item); } } catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { return; } catch (Exception) { await Task.Delay(TimeSpan.FromSeconds(2), stoppingToken); } } } }