Do not trust the engine's count as the pace
The second probe run read TxBufLen as 0 one millisecond and again fifty milliseconds after twenty-one characters had been pushed, while those characters were already going out: the first of them was decoded back off the air 420 ms later. The number is right when it is a second old and wrong when it is fresh, so it runs behind the engine. A pump that fed on it would have handed over the whole message in half a second and put all of it beyond reach, which is worse than the clock it replaced. So the clock is the pace again, and the count is a check on it: the engine is never given more than Lead + Slack characters however fast the clock says to feed, and a message ends when the count and the clock estimate both say it has. Characters fed since the last answer are added to it, so a stale answer cannot be spent twice. The engine is set to Character out: ABCD with no space after it went out at once. Word out would have held it, so the holding case stays, but it now needs the count to be neither going down nor being added to, since an engine kept exactly at the cap has a count that does not move either. The probe writes down every reading for two seconds after a push and does not believe an empty one in that window, which is what the run needed to measure the lag and did not do. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RtspmWmS7f8kUvcyaHpRWZ
This commit is contained in:
@@ -212,39 +212,29 @@ public class TypeAheadTests
|
||||
Assert.Equal(2, Sent.Length);
|
||||
}
|
||||
|
||||
/// An engine that says how much it holds is asked rather than timed, so
|
||||
/// nothing depends on the baud rate being right.
|
||||
/// The engine's count of what it has left runs behind what it is really
|
||||
/// doing: the probe read 0 fifty milliseconds after twenty-one characters
|
||||
/// had been pushed and were already going out. A pump that believed that
|
||||
/// would hand over the whole message at once, so the count only ever stops
|
||||
/// it, and the engine is never given more than `Lead` plus `Slack`.
|
||||
[Fact]
|
||||
public async Task ACountingEngineIsAskedHowMuchItHolds()
|
||||
public async Task AnEngineBehindTheClockIsNotFedPastTheCap()
|
||||
{
|
||||
FakeEngine engine = new();
|
||||
using TypeAhead buffer = new(engine, baud: Slow);
|
||||
// half the speed of the baud rate the pump is paced by
|
||||
using Timer transmitting = new(_ => engine.Transmit(1), null, 0, 200);
|
||||
|
||||
buffer.Append("CQ TEST");
|
||||
buffer.Append("CQ TEST DE OM5M");
|
||||
|
||||
await WaitForAsync(() => engine.Waiting.Length >= 2);
|
||||
await Task.Delay(30);
|
||||
Assert.Equal("CQ", engine.Waiting);
|
||||
|
||||
engine.Transmit(2);
|
||||
|
||||
await WaitForAsync(() => engine.Transmitted.Length + engine.Waiting.Length >= 4);
|
||||
Assert.Equal("CQ T", engine.Transmitted + engine.Waiting);
|
||||
}
|
||||
|
||||
/// MMTTY set to Word out holds a word until the space after it, so the
|
||||
/// count stops going down. Waiting for it to move would leave the message
|
||||
/// sitting there, so the pump feeds on.
|
||||
[Fact]
|
||||
public async Task AnEngineHoldingWhatItHasIsFedAnyway()
|
||||
{
|
||||
FakeEngine engine = new();
|
||||
using TypeAhead buffer = new(engine, baud: Slow);
|
||||
|
||||
buffer.Append("CQ TEST");
|
||||
|
||||
await WaitForAsync(() => engine.Waiting == "CQ TEST");
|
||||
Assert.Equal("CQ TEST", engine.Waiting);
|
||||
int most = 0;
|
||||
for (int look = 0; look < 50; look++)
|
||||
{
|
||||
most = Math.Max(most, engine.Waiting.Length);
|
||||
await Task.Delay(20);
|
||||
}
|
||||
Assert.True(most <= TypeAhead.DefaultLead + TypeAhead.Slack, $"the engine was given {most}");
|
||||
Assert.True(engine.Transmitted.Length > 0, "nothing was transmitted at all");
|
||||
}
|
||||
|
||||
/// The clock is the fallback for an engine that will not answer.
|
||||
|
||||
Reference in New Issue
Block a user