Ingress pressure experiment¶
Question¶
When a producer outpaces rendering, does ordered execution also limit queued input? Compare a burst with a producer that waits for each local batch to finish. This is an integration experiment for the next-stage plan, composing the TUI SDK, mixed xterm ingress, and private history renderer.
Method¶
probe.ts connects the real SDK byte writer to the real headless mixed ingress in one process, with encoded responses routed back to the SDK. After negotiation and Append, a test subclass holds the first Extend immediately before native rendering. The producer sends 16, 64, or 256 distinct ASCII fragments, either all at once or waiting after every eight or one SDK writes. The barrier is then released and the actual history renderer runs normally.
The counters surround ingress.push() and decrement when its Promise settles:
Unsettled pushes include the currently processing push and those waiting.
Unsettled bytes sum the original byte lengths of those pushes. They are not heap usage, buffered-character counts, or the adapter’s queue length.
Measurement covers only Extend writes, one SDK byte batch per Operation in these fixtures. Setup, subsequent Seal, ordinary output, and close are excluded.
While held, only the first Extend has reached Session commit and no fragment
has rendered. After release, assertions check exact Session text and rendered
rows, all Extends completed, zero outstanding counters, a following ordinary
DONE line appearing once, and successful Seal/Context closure. Session commit
precedes rendering while the barrier is held; agreement is checked after drain.
The controlled stall isolates queue growth. Batch sizes are experiment fixtures; latency and throughput are not measured.
Observed results¶
Local run on 2026-09-16, pinned xterm 6.0, 80-by-8 viewport, 1000 scrollback rows:
Extends |
Burst peak pushes / bytes |
Wait every 8: peak pushes / bytes |
Wait every 1: peak pushes / bytes |
|---|---|---|---|
16 |
16 / 3,738 |
8 / 1,872 |
1 / 234 |
64 |
64 / 14,970 |
8 / 1,872 |
1 / 234 |
256 |
256 / 60,690 |
8 / 1,912 |
1 / 239 |
All nine runs drained and passed the final-state assertions. Larger numeric IDs change encoded lengths, so the peak bytes for an eight-write batch need not be those of the first held batch. The three parameterized regression tests compare all three policies at each size and check their byte totals agree. Type checking and the full 179-test Node suite passed in the same checkout.
Conclusion and next boundary¶
The current ingress can preserve these fragments in order while outstanding input grows with a burst. Waiting at this local boundary limits outstanding pushes in the tested arrangements; ordering alone does not provide such a limit.
The fixture’s producer can directly await the terminal’s local completion
Promise; an external TUI cannot. The
SDK callback accepts bytes synchronously and an
Operation ID means sent, not rendered. Making that callback async would not
cause the current SDK to wait.
This probe deliberately omits the later opt-in limits so it can measure the unbudgeted queue. The trial resource policy now bounds owned pending input in the terminal-host example and its mixed ingress. The separate PTY pressure experiments test optional bridge credits and pause/resume, including a producer-waiting follow-up.
Run and limits¶
pnpm prototype:ingress-pressure
pnpm typecheck
pnpm test
The probe prints JSON; the root tests include pressure.test.ts. The barrier has a ten-second failure deadline and each regression has a thirty-second test deadline. No browser or child application is launched.
This checks one Block, finite Extend sequences, fixed ASCII layout, and normal completion after an artificial stall. It does not measure process memory, retained Session history, PTY/OS/WebSocket buffers, sustained throughput, browser responsiveness, native selection/search, eviction, or fault recovery. The xterm adapter uses private APIs and experimental OSC 9002.