fix(mtconnect): a delivered /sample chunk clears an unanswered-write degradation (review r2 N-5)
Coordinator ruling: a delivered chunk proves the Agent is alive (the analogue of OpcUaClient's good keep-alive), so TryMarkStreamDelivered - generation-checked under _subscriptionLock - also clears _writeDegraded. The degradation no longer sticks forever on a subscription-only driver. Test: unanswered write -> Degraded, stays Degraded with nothing else happening (positive control), the next chunk -> Healthy; red with the clear removed. Round-2 doc text corrected. Refs #743 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -371,9 +371,10 @@ public sealed partial class MTConnectDriver
|
||||
|
||||
/// <summary>
|
||||
/// Whether the last Agent write got no reply (review I-3 / coordinator ruling: an unanswered write degrades).
|
||||
/// Latched until the next answered <c>/current</c> read or answered write (<see cref="RecordReadAnswered"/> /
|
||||
/// <see cref="RecordWriteAnswered"/>). <b>Neither a <c>/sample</c> chunk nor a live-index read clears it</b>, so on
|
||||
/// a subscription-only driver one timed-out write keeps the driver Degraded until the next write (r1 N-5).
|
||||
/// Cleared by the next answered <c>/current</c> read, answered write (<see cref="RecordReadAnswered"/> /
|
||||
/// <see cref="RecordWriteAnswered"/>) or delivered <c>/sample</c> chunk of the current session
|
||||
/// (<see cref="TryMarkStreamDelivered"/>, r2 N-5) — so it cannot stick on a subscription-only driver. A read served
|
||||
/// from the live index does not clear it directly; the chunks behind that index do.
|
||||
/// </summary>
|
||||
private volatile bool _writeDegraded;
|
||||
|
||||
@@ -856,9 +857,8 @@ public sealed partial class MTConnectDriver
|
||||
|
||||
// The read path is answering (from a stream that is delivering), so a degradation a failed /current left
|
||||
// behind is no longer true of it. The stamp stays the pump's — this read heard nothing from the Agent itself.
|
||||
// Clears only the READ degradation (r1 N-5): an index read is the stream's evidence, not an Agent answer to a
|
||||
// request — the same evidence a /sample chunk carries, which by the I-3 ruling does not clear an unanswered
|
||||
// write either.
|
||||
// Clears only the READ degradation: an index read is derived from the stream's evidence — the chunks that fed the
|
||||
// index are what clear an unanswered write (TryMarkStreamDelivered, r2 N-5).
|
||||
if (_readDegraded)
|
||||
{
|
||||
_readDegraded = false;
|
||||
@@ -2751,6 +2751,11 @@ public sealed partial class MTConnectDriver
|
||||
|
||||
_streamDegraded = false;
|
||||
_pumpLive = true;
|
||||
|
||||
// r2 N-5 (coordinator): a delivered chunk proves the Agent is alive — the MTConnect analogue of OpcUaClient's
|
||||
// good keep-alive clearing a read/write Degraded — so it also clears an unanswered-write degradation, which
|
||||
// otherwise stuck forever on a subscription-only driver. Generation-checked with the rest (above).
|
||||
_writeDegraded = false;
|
||||
PublishHealthy(DateTime.UtcNow);
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user