docs(contracts): clarify ReplayGap drain-exclusion and resume-boundary semantics

Add two comment-only clarifications to mxaccess_gateway.proto (no field/number changes):
1. MxEvent.replay_gap: states the sentinel is ONLY ever set on StreamEvents events
   and is ALWAYS unset on DrainEventsReply events, preventing Task 12 from
   accidentally emitting it on the drain path and removing any client ambiguity.
2. ReplayGap.oldest_available_sequence: clarifies that the value IS retained and
   replayable, and that a client resumes gap-free by setting
   after_worker_sequence = oldest_available_sequence - 1 in the next
   StreamEventsRequest (receiving events starting at oldest_available_sequence).
Regenerated Generated/MxaccessGateway.cs (comment-only XML-doc change).
This commit is contained in:
Joseph Doherty
2026-06-16 05:09:47 -04:00
parent 9beb67c1e9
commit 85e4334bb7
2 changed files with 22 additions and 6 deletions
@@ -23592,6 +23592,9 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
/// clients MUST treat a present `replay_gap` as "you missed events — discard
/// local state and re-snapshot" and read `requested_after_sequence` /
/// `oldest_available_sequence` from it. Unset on every normal MXAccess event.
/// This field is ONLY ever set on events returned from the StreamEvents server
/// stream; it is ALWAYS unset on events in DrainEventsReply (the diagnostic
/// drain path never emits the sentinel).
/// Additive (proto3): existing clients that ignore this field continue to
/// deserialize the stream unchanged. (Reconnect/replay logic is Task 12; this
/// is the contract surface only.)
@@ -24491,9 +24494,14 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
public const int OldestAvailableSequenceFieldNumber = 2;
private ulong oldestAvailableSequence_;
/// <summary>
/// The oldest worker_sequence still retained in the replay ring. Events with
/// worker_sequence in (requested_after_sequence, oldest_available_sequence)
/// were evicted and are unrecoverable.
/// The oldest worker_sequence still retained in the replay ring and available
/// for replay. Events with worker_sequence in the open interval
/// (requested_after_sequence, oldest_available_sequence) were evicted and are
/// unrecoverable. oldest_available_sequence itself IS still retained: a client
/// that wishes to resume without incurring another gap MUST set
/// after_worker_sequence = oldest_available_sequence - 1 in the next
/// StreamEventsRequest, which will cause the server to replay starting at
/// oldest_available_sequence (the first retained event).
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@@ -725,6 +725,9 @@ message MxEvent {
// clients MUST treat a present `replay_gap` as "you missed events — discard
// local state and re-snapshot" and read `requested_after_sequence` /
// `oldest_available_sequence` from it. Unset on every normal MXAccess event.
// This field is ONLY ever set on events returned from the StreamEvents server
// stream; it is ALWAYS unset on events in DrainEventsReply (the diagnostic
// drain path never emits the sentinel).
// Additive (proto3): existing clients that ignore this field continue to
// deserialize the stream unchanged. (Reconnect/replay logic is Task 12; this
// is the contract surface only.)
@@ -750,9 +753,14 @@ message ReplayGap {
// The worker_sequence the client asked to resume after
// (StreamEventsRequest.after_worker_sequence).
uint64 requested_after_sequence = 1;
// The oldest worker_sequence still retained in the replay ring. Events with
// worker_sequence in (requested_after_sequence, oldest_available_sequence)
// were evicted and are unrecoverable.
// The oldest worker_sequence still retained in the replay ring and available
// for replay. Events with worker_sequence in the open interval
// (requested_after_sequence, oldest_available_sequence) were evicted and are
// unrecoverable. oldest_available_sequence itself IS still retained: a client
// that wishes to resume without incurring another gap MUST set
// after_worker_sequence = oldest_available_sequence - 1 in the next
// StreamEventsRequest, which will cause the server to replay starting at
// oldest_available_sequence (the first retained event).
uint64 oldest_available_sequence = 2;
}