Skip to content

daemon: make locks and clear-locks recover stale serial sessions #976

Description

@zackees

Problem

During a FastLED dual-board stress run, an interrupted Python runner left two SerialMonitor/serial clients alive. The fbuild daemon correctly saw the sessions as live, but from the CLI the recovery path was not actionable:

  • fbuild daemon locks reported held serial sessions by port/client id only.
  • fbuild daemon clear-locks has no flags/options and did not expose whether it can target open serial sessions.
  • The operator had to inspect external OS process state and manually kill orphaned Python processes before the daemon released COM11/COM9.

This made the daemon appear wedged even though the underlying issue was recoverable.

Observed

fbuild daemon locks during the wedge showed COM11 and COM9 held with client ids, but no owner process, age, command line, cwd, or last activity.

Daemon logs showed the daemon staying alive for roughly 24 minutes:

  • 2026-07-06T00:54:15Z - Daemon staying alive: 2 open serial sessions, 2 pending serial attaches
  • repeated once per minute through 2026-07-06T01:18:25Z
  • after killing orphaned .venv\Scripts\python.exe - clients, logs moved to 2 open serial sessions, then both ports closed:
    • COM11 client 2579d2ff-2c4b-4eed-a114-4f85c73d5b0d
    • COM9 client a3db3a9d-8966-4c3a-880c-9ab5ef81cd6c

Current CLI help:

fbuild daemon locks
Show lock status (project locks, serial sessions)
(no options)

fbuild daemon clear-locks
Clear stale locks
(no options)

Why this is separate from prior work

Related closed issues exist:

Those do not appear to cover the operator-facing recovery gap where a serial session is still considered live, but the CLI cannot identify the owning client or close a stale session by port/client id.

Requested behavior

Make serial-session lock diagnostics and recovery actionable from fbuild alone.

Suggested shape:

  • Include serial session metadata in fbuild daemon locks:
    • port
    • client id
    • session age
    • last activity / last read-write timestamp
    • pending attach age, if applicable
    • owner pid/process/argv/cwd when available
  • Add a targeted recovery command or flags, for example:
    • fbuild daemon clear-locks --serial --stale
    • fbuild daemon clear-locks --port COM11
    • fbuild daemon clear-locks --client-id <id>
    • or a dedicated fbuild daemon close-serial ...
  • If a session is still actively owned and should not be closed, the command should refuse with a concrete reason.

Acceptance criteria

  • From a state where COM ports are held by abandoned or stale serial sessions, an operator can identify the likely owner using fbuild daemon locks without external OS process inspection.
  • An operator can close stale serial sessions/pending attaches by port or client id using fbuild CLI alone.
  • The recovery command does not blindly kill unrelated active work; it either closes only stale sessions or reports why the session is considered live.
  • Regression coverage simulates a serial session/pending attach that stops making progress and verifies that locks exposes useful metadata and the recovery command releases the port.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions