mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
Starting a recording spans several steps — create the session directory, start the recorder, persist the trigger file, write the header — and only the last of them commits the recorder into the module's state. Anything throwing inside that window escaped the reactive collector, which then died for the rest of the process: the started recorder kept writing where nothing could stop it, the trigger file survived to re-attempt the dead session on every launch, and startRecorder() waited forever for a state nobody would publish. The debug log toggle stayed dead until reinstall. The whole start branch is now guarded. A failure rolls back first — stop the recorder, clear the log dir mirror, remove the trigger file, delete a session dir this attempt created — and only then decides what the failure means: our own scope dying still takes the collector with it, anything else (a cancellation from inside the start work included) is committed as a start failure and surfaced to the caller. shouldRecord is reset with it, so the every-state collector lands in the idle branch instead of retrying. The stop branch gets the same treatment: a recorder that cannot stop is logged and the cleared state committed anyway, so an awaiting stop completes. Recorder.stop() itself now guarantees logger removal, writer closure and reference clearing. Session directory names get a collision suffix, since a same-second retry would otherwise share a directory with the attempt it replaces, and the public start/stop entry points are serialized so two callers cannot race the same transition.