mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-10 01:09:43 +02:00
fix(tiles): final checkup review follow-ups
- docs/tile-grid-plan.md: the As built bullet on tile loads said a refresh
clears the screen at its turn in the queue. Since the fetch-first refresh it
fetches at its turn, keeps the last frame through the wait and its own round
trip, and resets with the queued in-stream \x1bc only once the capture is in
hand; a failed, aborted or empty fetch writes nothing and resets nothing.
- docs/architecture-invariants.md: the tile grid's One load queue paragraph
gets the same correction, and its list of captures that go through the
TileLoadQueue now names the server {t:'c'} refresh and the dropped-output
recovery refresh.
- test/terminal-tile-input.test.ts: destroy() cancelling a pending recovery is
now pinned on the timer itself (armed before destroy(), null right after it,
read before any timer runs), since the recovery callback's own destroyed
guard made the fetch check pass either way; a second test pins that
destroy() starts the live-output count over, so a write callback xterm still
owed counts nothing. Both fail with the _resetLiveFlow() call removed from
destroy().
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1040,12 +1040,33 @@ describe('TerminalTile live-output flow control: a flood cannot pile up in xterm
|
||||
fetchMock.mockClear();
|
||||
term.throwOnWrite = 'boom';
|
||||
out(ws, 'boom');
|
||||
const flow = tile as unknown as { _dropRecoveryTimer: unknown; _liveDropped: boolean };
|
||||
expect(flow._dropRecoveryTimer).not.toBeNull(); // the drop armed one recovery
|
||||
|
||||
tile.destroy();
|
||||
// Cleared by destroy() itself, read before any timer runs: the timer's own
|
||||
// callback nulls the field and its destroyed guard skips the fetch, so the
|
||||
// fetch check below alone cannot tell a cleared timer from a leaked one.
|
||||
expect(flow._dropRecoveryTimer).toBeNull();
|
||||
expect(flow._liveDropped).toBe(false);
|
||||
await vi.advanceTimersByTimeAsync(5000);
|
||||
|
||||
expect(fetchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('destroy() starts the count over: a write callback xterm still owed counts nothing', async () => {
|
||||
TileStatics.LIVE_BACKLOG_BUDGET = 100;
|
||||
const { tile, ws, term } = await connectTile(makeApp());
|
||||
ws.open();
|
||||
term.holdParse = true;
|
||||
out(ws, 'a'.repeat(60));
|
||||
expect(inFlight(tile)).toBe(60);
|
||||
|
||||
tile.destroy();
|
||||
expect(inFlight(tile)).toBe(0);
|
||||
term.parse(); // a callback from before destroy() carries the old epoch
|
||||
expect(inFlight(tile)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the server coming back kicks Pane B', () => {
|
||||
|
||||
Reference in New Issue
Block a user