command_queue Control Channel

command_queue is the control channel used to send runtime commands into s6.app._track_runtime.TrackRuntime. It is separate from the data queue, which carries processed frame outputs back to the UI or another consumer.

The queue items are two-tuples:

(CommandSet.<NAME>, payload)

CommandSet and PlaybackMode live in src/s6/app/_common.py. External callers can also use CommandSet.parse_message() when they need to accept a JSON-style message of the form {"command": ..., "payload": ...}.

How The Queue Is Consumed

s6 track --ui and s6 track --uplink run a spawned worker process with TrackRuntime. ContextGenerator.run(...) also delegates to TrackRuntime when a command queue is supplied. The runtime drains commands before selecting the next replay frame and again immediately before inference starts, so a late seek or pause can skip a stale replay frame before it reaches the pipeline.

The runtime handles these commands for all sources:

  • RECORD toggles dataset writing on and off.

  • TAKESNAPSHOT marks the next frame for a one-off dataset write.

  • SETEVOFFSET stores an exposure offset value.

  • SETCONTRAST stores a contrast offset value.

Dataset replay adds these playback commands:

  • PLAYBACKCONTROL with PlaybackMode.PLAY, PAUSE, STOP, BACKWARD, and FORWARD

  • GOTOFRAME

  • CHANGEDATASET

Replay state is worker-owned:

  • GOTOFRAME is atomic: seek to the target, pause replay, run the pipeline for that target, and publish the processed result.

  • BACKWARD and FORWARD pause playback, step relative to the last rendered frame, run the pipeline for that adjacent frame, and stay paused.

  • PAUSE stops supplying new replay frames after the current in-flight frame completes.

  • PLAY resumes from the frame after the last rendered paused frame.

  • STOP seeks to frame 0, renders it once, and leaves replay stopped.

Replay-only commands sent to live GST inputs do not stop streaming. The runtime keeps live frames flowing and reports an unavailable-command status in the next UI state message.

Exposure and contrast adjustments are applied during dataset replay to the left and right images. They are not applied by the base generator itself.

Current Wiring

src/s6/app/_gui.py is the main producer of commands today:

  • The merged play/pause action and the one-shot stop/step actions emit PLAYBACKCONTROL.

  • The seek slider emits GOTOFRAME as scrubbing changes the selected frame, and again on release if needed.

  • Snapshot and record controls emit TAKESNAPSHOT and RECORD.

The current GUI does not expose dataset switching, EV offset, or contrast controls. CHANGEDATASET, SETEVOFFSET, and SETCONTRAST remain available for other command producers.

src/s6/app/track.py creates a command queue for the spawned worker in the --ui and --uplink paths and passes it to TrackRuntime. In headless mode, track calls run() without a command queue, so no interactive commands are consumed. The default uplink path does not produce commands, but it still allocates the queue.

The paired data queue now has two payload modes:

  • UI-style consumers receive TrackFrameMessage(context=..., state=...).

  • s6 track --uplink receives only {"export": ...} snapshots.

The worker drops old data-queue items before publishing a new item. That keeps the UI and uplink consumers on the newest processed result. The GUI also holds a pending slider seek until the worker publishes the requested paused frame, so any already-queued pre-seek playback message cannot snap the seek bar back.

HTTP Helper

command_router(command_queue) in src/s6/app/_common.py exposes the same commands as FastAPI endpoints:

  • POST /record

  • POST /snapshot

  • POST /playback

  • POST /goto

  • POST /dataset

  • POST /ev_offset

  • POST /contrast

The helper returns 503 if no queue was provided. The repository currently defines the router helper, but does not mount it anywhere by default.

Notes

  • Command draining is non-blocking and does not rely on qsize().

  • The generator writes to the output dataset only when recording is enabled or a snapshot is pending; TrackRuntime owns when those writes occur in interactive runs.

  • DatasetContextGenerator still owns raw dataset reads, frame metadata, and timestamp pacing helpers, but interactive replay position and playback mode are owned by TrackRuntime.