using ScadaLink.Commons.Messages.Integration; namespace ScadaLink.AuditLog.Central; /// /// Mockable abstraction over the central-side PullAuditEvents gRPC /// client surface that uses to /// fetch the next reconciliation batch from a specific site. Extracted so the /// actor can be unit-tested against an in-memory stub without standing up a /// real GrpcChannel per site. /// /// /// /// The production implementation (host wiring task) wraps the auto-generated /// SiteStreamService.SiteStreamServiceClient, multiplexing one /// GrpcChannel per site keyed on /// . Until that wiring lands the DI /// composition root binds a NoOp default that returns an empty response — the /// reconciliation tick is still scheduled and the cursor logic still runs, so /// regressions in the actor itself are caught even before the real client /// arrives. /// /// /// Implementations MUST NOT throw on transport faults that the actor can /// tolerate (connection refused, deadline exceeded). The actor's contract is /// "one site's failure doesn't sink the rest of the tick"; an exception still /// won't crash the actor (the per-site try/catch catches it), but returning /// an empty response on a known-recoverable error keeps the logs cleaner. /// /// public interface IPullAuditEventsClient { /// /// Issues a PullAuditEvents RPC against the site whose endpoint /// is registered against . Returns the next /// batch of /// rows ordered oldest-first AND a MoreAvailable flag the actor /// uses to decide whether to fire another pull immediately. /// Task PullAsync( string siteId, DateTime sinceUtc, int batchSize, CancellationToken ct); }