Live TCP Streaming Export
Stream a running session over TCP so the Workbench can watch a process tick-by-tick, right now.
Status: โ Implemented ยท Visibility: Public ยท Level: ๐ต Core ยท Category: Profiler
๐ฏ What it solves
Waiting for a process to exit โ or crash โ before you can look at its trace doesn't work when you're chasing a live stall, watching memory climb during a soak test, or want to see a load test's behavior as it happens. Live export lets a Workbench viewer attach directly to a running process's socket and see events arrive as they're produced, with no file round-trip and no restart required.
โ๏ธ How it works (in brief)
TcpExporter listens on one TCP port and accepts a single client at a time. On connect it sends an Init frame
(the same header + metadata tables as the file format) and then a stream of Block frames, one per drained batch,
LZ4-compressed the same way as file export. It also re-sends a small catch-up frame โ currently-claimed thread
names โ about once a second, so a viewer that attaches mid-session still gets correct lane labels. Sends are
non-blocking: a frame that can't be written immediately is dropped rather than stalling the exporter thread. On
profiler stop, a Shutdown frame closes the session cleanly.
๐ป Usage
// typhon.telemetry.json โ zero code:
// { "Typhon": { "Telemetry": { "Enabled": true,
// "Profiler": { "Enabled": true, "Live": 9100, "LiveWaitMs": 5000 } } } }
using Typhon.Engine;
var runtime = TyphonRuntime.Create(dbe, schedule =>
{
schedule.PublicTrack.DeclareDag("Sim").CallbackSystem("Tick", ctx => RunGameLogic(ctx));
});
// LiveWaitMs > 0 blocks Create() until the first viewer connects (or the timeout elapses).
// ... run the workload; in the Workbench: File โ Connect Live โ "localhost:9100" ...
| Config key | Default | Effect |
|---|---|---|
Typhon:Profiler:Live |
unset (no live export) | TCP port to listen on; any non-numeric value falls back to port 9100 |
Typhon:Profiler:LiveWaitMs |
0 (don't wait) |
Milliseconds TyphonRuntime.Create blocks waiting for the first viewer to attach before returning |
โ ๏ธ Guarantees & limits
- Single client only โ a second connection attempt while a viewer is attached is rejected outright; run a
second session on a different
Liveport if you need a second observer. - No persistence โ bytes never delivered over this socket cannot be replayed; a live-only session has no
equivalent of the file's completeness. Set both
TraceandLivetogether to keep a durable copy while also watching live. - Drop-on-backpressure, not stall โ a slow client causes individual frames to be dropped
(
SocketError.WouldBlock) rather than backing up the profiler consumer thread; expect gaps in a chronically slow viewer's feed rather than delay. - Silent disconnect handling โ if the viewer's connection drops, the engine keeps running and simply accepts the next client; there's no application-visible error.
LiveWaitMsonly gates startup once โ it blocksTyphonRuntime.Createfor the first connection; a later reconnect after the viewer disconnects does not re-block anything.- Plain TCP, no platform dependency โ works identically on Windows/Linux/macOS, unlike the ETW-based off-CPU scheduling extension.
๐งช Tests
- TcpExporterIntegrationTests โ Init/Block frame round-trip over a loopback socket, plus
LiveWaitMs/live-connect-timeout blocking-vs-non-blocking connect behavior
๐ Related
- Source:
src/Typhon.Engine/Profiler/internals/TcpExporter.cs - Parent feature: Trace Export
- Sibling: File-Based Trace Export (.typhon-trace) โ the other trace-export sink; both can attach to the same session at once