Files
led2/.planning/phases/05-live-show-execution/05-01-SUMMARY.md
Claude 7809402d54 docs(05-01): complete cue scheduler plan — SUMMARY, STATE, ROADMAP updated
- 05-01-SUMMARY.md created with task commits, decisions, next-phase readiness
- STATE.md advanced to plan 2/3, progress 88%, decisions logged
- ROADMAP.md updated: phase 5 in progress (1/3 summaries)
- REQUIREMENTS.md: SHW-03 marked complete
2026-04-07 10:12:09 +00:00

4.9 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
05-live-show-execution 01 api
websocket
udp
cue-scheduler
animation
fastapi
lightsync
phase provides
04-timeline-editor Show model with tracks/cues and encode_animation_cmd UDP encoder
Server-side cue scheduler in websocket tick handler that fires UDP animation commands at correct timestamps
Per-connection show state (show, fired_ids, is_playing) scoped to each WebSocket connection
preview_update broadcast messages sent to all clients on each tick
Seek-safe fired_ids rebuild preventing double-fire or missed cues after seeking
05-02 (live preview UI consumes preview_update messages)
05-03 (keyboard shortcuts drive play/pause/seek which gates cue scheduler)
added patterns
Per-connection mutable state pattern for WebSocket handlers (show, fired_ids, is_playing)
60ms LOOKAHEAD window for cue scheduling with fire-and-forget UDP dispatch
Seek-safe fired_ids set comprehension rebuild from show cues before seek position
active_cue tracking per track for preview state (not just newly-fired cues)
Batch preview_update broadcast after each tick's cue scheduling pass
created modified
lightsync/api/ws.py
LOOKAHEAD = 0.060 (60ms) defined inline per tick — not a module constant — matches D-02 spec
is_playing gate on cue scheduler prevents any cue firing during pause or seek drag
Past cues (>100ms behind position) silently marked fired without UDP dispatch — prevents late blasts on seek
active_cue tracking includes already-fired cues still within their duration window — preview stays lit for duration of block
import lightsync.main as _main inside load handler — deferred import avoids circular import at module level
Pattern: Per-connection WebSocket state — mutable variables scoped inside async handler function
Pattern: Seek rebuild — set comprehension over all tracks/cues to mark past cues fired
Pattern: Preview batching — collect preview_updates list then broadcast after cue loop
SHW-03
8min 2026-04-07

Phase 5 Plan 01: Live Show Execution — Cue Scheduler Summary

WebSocket tick handler extended with 60ms look-ahead cue scheduler that fires UDP animation commands at exact timestamps, with seek-safe fired_ids rebuild and preview_update broadcast on every tick

Performance

  • Duration: 8 min
  • Started: 2026-04-07T10:09:19Z
  • Completed: 2026-04-07T10:17:00Z
  • Tasks: 2
  • Files modified: 1

Accomplishments

  • Per-connection show state (show, fired_ids, is_playing) integrated into WebSocket handler
  • Load message extended to load show from show_store by show_id, resetting scheduler state
  • Play/pause handlers gate is_playing flag (pause never touches fired_ids per spec)
  • Seek handler rebuilds fired_ids via set comprehension over all cues before seek position
  • 60ms LOOKAHEAD cue scheduler fires UDP animation commands during active playback
  • Past cues (>100ms behind) silently skipped — no late UDP bursts after seek
  • active_cue tracking covers both newly-fired and already-active cues for preview continuity
  • preview_update messages broadcast to all connected clients on each tick tick (active and clear states)

Task Commits

Each task was committed atomically:

  1. Task 1: Add per-connection show state and load handler to ws.py - 3d36cc5 (feat)
  2. Task 2: Add cue scheduling loop and preview_update broadcast to tick handler - 64c49c9 (feat)

Files Created/Modified

  • lightsync/api/ws.py - Extended with cue scheduler, show loading, play/pause/seek handlers, preview_update broadcast

Decisions Made

  • LOOKAHEAD = 0.060 defined inline inside the tick branch (not as module constant) — keeps it local to the scheduler logic
  • Deferred import of lightsync.main as _main inside the load handler body to avoid circular import at module level
  • active_cue tracks already-fired cues still within their duration window so preview stays lit for the full block duration, not just at fire time
  • Past-cue threshold set at 100ms (not 60ms) to give a small recovery window without causing stale fires

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None. The Python runtime was invoked via uv run python (no python/python3 on PATH in this environment).

Next Phase Readiness

  • WebSocket cue scheduler is fully functional — ready for 05-02 (live preview UI consuming preview_update messages)
  • preview_update messages broadcast device_id, animation name, and color on each tick — frontend can render device state
  • Seek and pause behavior are correct per spec — no double-fire, no late blasts

Phase: 05-live-show-execution Completed: 2026-04-07