Commit f9b2c83a by PLN (Algolia)

fix(lcxl-leds): the LED daemon was mute in the journal — twice over (#106)

Take 94 came back with no track trail, and there was no way to tell from the logs
whether the watcher had seen the track changes, failed to bind them, or simply
never run. It had been running for 2h46m. It had emitted nothing but systemd's own
start/stop lines the entire time.

Two independent causes, and either alone is enough to blind the unit:

1. Python BLOCK-buffers stdout when it is a pipe, and under systemd it always is.
   Even the lines that were being printed would have sat unflushed in a 4 KB
   buffer. Fixed with Environment=PYTHONUNBUFFERED=1 in the unit.

2. `--watch -q` suppressed the track-change line itself, so there was nothing to
   flush. That is the wrong thing to make quiet. `quiet` should mean "no per-CC
   chatter" — thousands of lines an hour — not "never say what you are painting",
   which is a handful of lines an hour and the entire purpose of the daemon. The
   track-change log is now unconditional.

Verified live rather than by reading: restarted the unit, wrote a different track
to ~/.cache/parvagues/current-track, restored the original, and read the journal
back. Both transitions appear with their binding counts (desire 28 controls,
vague_de_crime 20), and a re-parse of the same file is labelled distinctly from a
real track change — that distinction matters because an edit-and-save must keep
the touched-state while a genuine track change must clear it.

Same family as the stale-binding pattern this rig keeps producing: something
resolved once, invalidated by an event, with no error anywhere. Here the error
reporting itself was the thing that had been silently resolved to /dev/null.
parent cc9cbf48
......@@ -15,6 +15,12 @@ StartLimitIntervalSec=0
[Service]
Type=simple
WorkingDirectory=/home/pln/Work/Sound/Tidal
# Python BLOCK-buffers stdout when it is a pipe, and under systemd it always is.
# So this unit produced no journal output beyond systemd's own lines, and its
# track-change diagnostics never reached the journal — which is why take 94 could
# not be explained from the logs even though the watcher ran throughout it. A
# daemon whose diagnostics sit unflushed in a 4 KB buffer is a daemon with none.
Environment=PYTHONUNBUFFERED=1
ExecStart=/usr/bin/python3 /home/pln/Work/Sound/Tidal/tools/lcxl-leds.py --watch -q
Restart=always
......
......@@ -1088,6 +1088,17 @@ def cmd_watch(s: Sender, track: str | None, reassert: float = 30.0,
touched.clear()
painter.set_frame(build_frame(state["bindings"], dict(values),
set(touched)))
# UNCONDITIONAL, even under -q. `quiet` should mean "no per-CC
# chatter", not "never say what you are painting": under systemd this
# unit emitted nothing but systemd's own lines, so when take 94 came
# back with no track trail there was no way to tell whether the
# watcher had seen the track change, failed to, or never ran. One line
# per track change is a few an hour and it is the entire point of the
# daemon. (The unit also needs PYTHONUNBUFFERED=1 — Python
# block-buffers stdout to a pipe, so even these would have sat
# unflushed.)
print(f"lcxl-leds: {'re-parsed' if same_track else 'TRACK'} "
f"{t or '(none)'} → {len(state['bindings'])} controls")
if follow:
threading.Thread(target=follow_loop, daemon=True).start()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment