using Microsoft.Extensions.Logging.Abstractions; using ZB.MOM.WW.MxGateway.Server.Configuration; using ZB.MOM.WW.MxGateway.Server.Dashboard.Hubs; using ZB.MOM.WW.MxGateway.Server.Grpc; using ZB.MOM.WW.MxGateway.Server.Metrics; namespace ZB.MOM.WW.MxGateway.Server.Sessions; /// /// Dependencies a needs to construct and own its /// . Bundled so the session constructor stays a /// single optional parameter rather than four, and so unit tests that build a session /// directly get a working distributor from without wiring DI. /// /// /// Maps worker IPC WorkerEvent frames to public MxEvents. The distributor /// pump applies this once per event in worker order, mirroring the mapping /// EventStreamService.ProduceEventsAsync used previously. /// /// /// Supplies the distributor's per-subscriber queue capacity and replay ring-buffer /// bounds (, /// , /// ). /// /// Logger for the distributor pump lifecycle. /// Clock used to timestamp and age-evict replay entries. /// /// Gateway metrics sink used by the session's per-subscriber overflow handler to record /// the queue-overflow counter and, for legacy single-subscriber FailFast, the session /// fault. Carrying it here keeps the distributor decoupled from the metrics type while /// preserving the observability the pre-epic per-RPC overflow path emitted. /// /// /// Sink the session's internal dashboard mirror loop publishes raw session /// MxEvents to. When non-null the session registers an internal distributor /// subscriber on becoming Ready and mirrors every fanned event to the dashboard /// EventsHub group regardless of whether a gRPC client is streaming. When null /// (unit tests that don't exercise the dashboard mirror) no mirror is started. /// /// /// The session's effective multi-subscriber mode. Carried here so the session /// can pass it to its at construction — the /// distributor is created at MarkReady (for the dashboard mirror) before any gRPC /// subscriber attaches, so the mode cannot be learned from a later /// AttachEventSubscriber call. The distributor gates its FailFast session-fault /// decision on this mode (single-subscriber only) instead of a live count snapshot, /// closing the false-FailFast race. Defaults to /// (single-subscriber) so existing call sites and unit tests are unchanged. /// public sealed record SessionEventStreaming( MxAccessGrpcMapper Mapper, EventOptions EventOptions, ILogger DistributorLogger, TimeProvider TimeProvider, GatewayMetrics Metrics, IDashboardEventBroadcaster? DashboardBroadcaster = null, bool AllowMultipleEventSubscribers = false) { /// /// Defaults used when a session is constructed without explicit streaming /// dependencies (unit tests). Uses a fresh mapper, default event options, a no-op /// logger, the system clock, a fresh metrics sink, and no dashboard mirror. /// public static SessionEventStreaming Default { get; } = new( new MxAccessGrpcMapper(), new EventOptions(), NullLogger.Instance, TimeProvider.System, new GatewayMetrics()); }