using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using ZB.MOM.WW.MxGateway.Contracts.Proto; using ZB.MOM.WW.MxGateway.Worker.Sta; namespace ZB.MOM.WW.MxGateway.Worker.MxAccess; /// /// Manages the runtime session between the worker and the MXAccess COM instance on an STA thread. /// public interface IWorkerRuntimeSession : IDisposable { /// /// Starts the session, creates the MXAccess COM object, and returns ready metadata. /// /// Identifier of the session. /// ID of the worker process. /// Token to cancel the asynchronous operation. /// Asynchronous task returning worker readiness metadata. Task StartAsync( string sessionId, int workerProcessId, CancellationToken cancellationToken = default); /// /// Dispatches an STA command to the MXAccess runtime and returns the reply. /// /// STA command to execute on the STA thread. /// Asynchronous task returning the command reply. Task DispatchAsync(StaCommand command); /// /// Captures a heartbeat snapshot of the runtime state. /// /// The current heartbeat snapshot. WorkerRuntimeHeartbeatSnapshot CaptureHeartbeat(); /// /// Drains up to the specified number of pending events from the queue. /// /// Maximum number of events to drain. /// List of drained events. IReadOnlyList DrainEvents(uint maxEvents); /// /// Drains pending events bounded by both a count cap and a byte budget, so a caller building a /// single reply frame never removes an event it cannot ship. /// /// /// Declared as a second method rather than a default interface method: the worker targets /// .NET Framework 4.8, which has no runtime support for default interface members. /// /// Maximum number of events to drain; 0 means "no count limit". /// Byte budget for the drained events' estimated serialized size. /// The drained events and the truncation facts describing what stayed queued. WorkerEventDrainResult DrainEvents(uint maxEvents, int maxTotalBytes); /// /// Waits until the outbound event queue has something for the caller to look at (an /// enqueued event or a recorded fault), the fallback timeout elapses, or the token is /// cancelled. Lets a drain loop be signal-driven instead of polling. /// /// /// Declared on the interface because the pipe session only ever sees an /// , never the queue behind it; .NET Framework 4.8 has /// no default interface members, so every implementation supplies it. The wait's outcome is /// not surfaced: the caller re-drains and re-checks after every /// wait, because the signal is coalesced and the timeout is a ceiling, not a poll period. /// /// Precondition: at most one waiter. The implementation's wake signal carries a /// single permit, which is sufficient only because a session has exactly one event /// drain loop; a second concurrent waiter would degrade to the fallback timeout. /// /// /// Maximum time to wait before the wait completes unsignalled. /// Token cancelling the wait. /// A task that completes when the queue is signalled or the timeout elapses. Task WaitForEventsAsync(TimeSpan timeout, CancellationToken cancellationToken); /// /// Drains a pending fault from the queue, if any. /// /// The pending fault, or if none is queued. WorkerFault? DrainFault(); /// /// Cancels a pending command by correlation ID. /// /// Correlation ID of the command to cancel. /// True if the command was found and cancelled; otherwise, false. bool CancelCommand(string correlationId); /// /// Requests a graceful shutdown of the session. /// void RequestShutdown(); /// /// Shuts down the session gracefully within the specified timeout. /// /// Maximum time to allow for graceful shutdown. /// Token to cancel the asynchronous operation. /// Asynchronous task returning the shutdown result. Task ShutdownGracefullyAsync( TimeSpan timeout, CancellationToken cancellationToken = default); }