fix(mtconnect): Unsupported latch inside the checked section; live-index reads do not clear a write degradation (review r1 N-4, N-5)
- N-4: the /sample Unsupported latch is set inside TryDegradeStream's generation-checked critical section (latchUnsupported), so a superseded pump can no longer latch it on the session that replaced it. - N-5: a read served from the live pump index clears only the read degradation - it is stream evidence, like a chunk, which by the I-3 ruling does not clear an unanswered write. The 'cannot stick' wording in the XML doc and docs/drivers/MTConnect.md now states the latch-until-next-answered-/current-read- or-write behaviour, incl. the subscription-only consequence. Tested (chunk + live-index read keep Degraded; an answered write clears it). Refs #743 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
@@ -165,4 +165,37 @@ public sealed class MTConnectBatchedWriteTests
|
||||
|
||||
driver.GetHealth().State.ShouldBe(DriverState.Degraded);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// r1 N-5: stream evidence does not clear an unanswered write — neither a delivered /sample chunk nor a read
|
||||
/// served from the live pump index. The next answered write does (the positive control).
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Stream_evidence_does_not_clear_an_unanswered_write_but_an_answered_write_does()
|
||||
{
|
||||
var (driver, client) = await WritableAsync();
|
||||
try
|
||||
{
|
||||
await driver.SubscribeAsync([PosRaw], TimeSpan.FromMilliseconds(50), Ct);
|
||||
await client.PumpAsync(MTConnectPumpGenerationChunks.Pos(108, 113, "1.5")).WaitAsync(TimeSpan.FromSeconds(30), Ct);
|
||||
client.WriteFailure = new HttpRequestException("connection refused");
|
||||
await driver.WriteAsync([new WriteRequest(PosRaw, 9.5)], Ct);
|
||||
driver.GetHealth().State.ShouldBe(DriverState.Degraded);
|
||||
var currentCalls = client.CurrentCallCount;
|
||||
|
||||
await client.PumpAsync(MTConnectPumpGenerationChunks.Pos(113, 118, "2.5")).WaitAsync(TimeSpan.FromSeconds(30), Ct);
|
||||
(await driver.ReadAsync([PosRaw], Ct)).Single().StatusCode.ShouldBe(Good);
|
||||
client.CurrentCallCount.ShouldBe(currentCalls, "the read was served from the live index");
|
||||
|
||||
driver.GetHealth().State.ShouldBe(DriverState.Degraded, "stream evidence is not an answer to the write");
|
||||
|
||||
client.WriteFailure = null;
|
||||
await driver.WriteAsync([new WriteRequest(PosRaw, 3.5)], Ct);
|
||||
driver.GetHealth().State.ShouldBe(DriverState.Healthy);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await driver.ShutdownAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user