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:
@@ -23592,6 +23592,9 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
|
|||||||
/// clients MUST treat a present `replay_gap` as "you missed events — discard
|
/// clients MUST treat a present `replay_gap` as "you missed events — discard
|
||||||
/// local state and re-snapshot" and read `requested_after_sequence` /
|
/// local state and re-snapshot" and read `requested_after_sequence` /
|
||||||
/// `oldest_available_sequence` from it. Unset on every normal MXAccess event.
|
/// `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
|
/// Additive (proto3): existing clients that ignore this field continue to
|
||||||
/// deserialize the stream unchanged. (Reconnect/replay logic is Task 12; this
|
/// deserialize the stream unchanged. (Reconnect/replay logic is Task 12; this
|
||||||
/// is the contract surface only.)
|
/// is the contract surface only.)
|
||||||
@@ -24491,9 +24494,14 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
|
|||||||
public const int OldestAvailableSequenceFieldNumber = 2;
|
public const int OldestAvailableSequenceFieldNumber = 2;
|
||||||
private ulong oldestAvailableSequence_;
|
private ulong oldestAvailableSequence_;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The oldest worker_sequence still retained in the replay ring. Events with
|
/// The oldest worker_sequence still retained in the replay ring and available
|
||||||
/// worker_sequence in (requested_after_sequence, oldest_available_sequence)
|
/// for replay. Events with worker_sequence in the open interval
|
||||||
/// were evicted and are unrecoverable.
|
/// (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>
|
/// </summary>
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
|
[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
|
// clients MUST treat a present `replay_gap` as "you missed events — discard
|
||||||
// local state and re-snapshot" and read `requested_after_sequence` /
|
// local state and re-snapshot" and read `requested_after_sequence` /
|
||||||
// `oldest_available_sequence` from it. Unset on every normal MXAccess event.
|
// `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
|
// Additive (proto3): existing clients that ignore this field continue to
|
||||||
// deserialize the stream unchanged. (Reconnect/replay logic is Task 12; this
|
// deserialize the stream unchanged. (Reconnect/replay logic is Task 12; this
|
||||||
// is the contract surface only.)
|
// is the contract surface only.)
|
||||||
@@ -750,9 +753,14 @@ message ReplayGap {
|
|||||||
// The worker_sequence the client asked to resume after
|
// The worker_sequence the client asked to resume after
|
||||||
// (StreamEventsRequest.after_worker_sequence).
|
// (StreamEventsRequest.after_worker_sequence).
|
||||||
uint64 requested_after_sequence = 1;
|
uint64 requested_after_sequence = 1;
|
||||||
// The oldest worker_sequence still retained in the replay ring. Events with
|
// The oldest worker_sequence still retained in the replay ring and available
|
||||||
// worker_sequence in (requested_after_sequence, oldest_available_sequence)
|
// for replay. Events with worker_sequence in the open interval
|
||||||
// were evicted and are unrecoverable.
|
// (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;
|
uint64 oldest_available_sequence = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user