using ZB.MOM.WW.OtOpcUa.Commons.Messages.Deploy;
namespace ZB.MOM.WW.OtOpcUa.Runtime.Communication;
///
/// Posts this node's deployment acknowledgment to central over the mesh_transport.v1
/// command plane (mesh gRPC command plane, Phase 1B). The seam
/// uses under MeshTransport:Mode = Grpc, in place of
/// the node-local DistributedPubSub publish it uses under Dps.
///
///
///
/// One ack per node per dispatch. Whatever the implementation does about redundancy, it
/// posts to one central endpoint at a time rather than fanning out — the semantic of the
/// one-ack-per-node-per-dispatch semantic the deploy coordinator counts on.
/// This is defence in depth, not a correctness dependency: the coordinator counts acks
/// in a NodeId-keyed dictionary behind an expected-set membership guard
/// (ConfigPublishCoordinator.HandleAck), so a duplicate from one node overwrites its own
/// entry and cannot inflate the count or seal a deployment early. What fan-out would actually
/// cost is duplicated work at central, doubled deploy-ack rows written, and a transport whose
/// delivery count nobody can reason about — none of which is worth having.
///
///
/// Fire-and-forget, and it never throws. The caller is an actor that discards the
/// returned task, so an exception escaping here would become an unobserved task fault — the
/// silent drop this migration exists to remove. An implementation reports failure by logging
/// and returning, never by faulting the task.
///
///
public interface IApplyAckSender
{
/// Posts to central, or logs why it could not be.
/// The per-node apply acknowledgment.
/// Cancels the in-flight call.
///
/// A task that completes when the attempt finishes, successfully or not. It never faults —
/// see the remarks.
///
Task SendAsync(ApplyAck ack, CancellationToken cancellationToken = default);
}