Repository navigation
Status is only refreshed at init, so it goes blank after any cache loss or machine restart #5
Description
Follow-up to #4, which is now fixed at the infrastructure level — a shared Redis is deployed (sengine-cloud/fluxcd-infra#165) and the Machines page does update from a print:
status=110 'dispatched 1 label(s)' (during the print)
status=100 'fw 2.1.2 · 90% (4.10V) · media ok · Q223P4C31420105' (settled)
That works. This issue is about what happens afterwards.
The gap
_refresh_status() — the only thing that reads the retained topic and produces the rich text — is called from init_machine() and nowhere else. Every other status write comes from print_labels, which sets PRINTING or a job outcome.
So the rich status is written exactly once per machine initialisation, and any event that clears or bypasses the shared state leaves the page showing a bare default until something re-initialises the machine. Observed today, both reproducible:
- Redis restarted (a config rollout, but a node reclaim or eviction does the same — the instance is deliberately non-persistent). All
machine:*keys vanish; the page readsstatus=101,text='', because those are the defaultsget_shared_statereturns for missing keys. POST /api/machine/<pk>/restart/clears the state and does not appear to callinit_machinepromptly. The machine reportsinitialized: True,is_driver_available: True,machine_errors: []— healthy in every respect — while showingstatus=101,text=''indefinitely. Only a pod restart brought it back.
Note text='' is itself diagnostic: no code path in this driver produces an empty status text. Both branches of _refresh_status write something, so an empty string means the driver never ran, not that it ran and found nothing.
Why it matters more now, not less
Before #4 was fixed, the page was permanently stale and everyone knew it. Now it is usually accurate, which makes the occasional blank more misleading — UNKNOWN with no text looks like a printer problem when it is a cache lifecycle artifact.
Suggested direction
Refresh status on more than just init. Cheapest useful version: call _refresh_status(machine) at the end of print_labels, so a print leaves the page showing the printer's settled state rather than PRINTING forever (which is what happens today with AWAIT_RESULT_S=0, the default). That costs one retained-topic read per print, on a path that has already done far more expensive work.
A periodic refresh would cover the idle case too, but the machine framework does not obviously offer a hook for it, and polling MQTT on a timer for an idle printer is a worse trade than accepting staleness until the next print.
Worth considering separately: when the driver finds no retained status it currently reports UNKNOWN — 'no retained status; the print agent has not published yet'. That text is right for a genuinely fresh agent and misleading after a cache wipe, where the agent has published and we simply lost our copy. Distinguishing the two would need the driver to know whether the cache was recently cleared, which it cannot — so the honest fix may just be softening the wording.
Activity
impuls42 commentedon Jul 30, 2026
Fixed in #6 — and the issue text was wrong on the part that mattered most.
I wrote that "a periodic refresh would cover the idle case too, but the machine framework does not obviously offer a hook for it". It does:
MACHINE_PING_ENABLEDdefaults toTrueand isTrueon this instance. So the periodic refresh I dismissed was available the whole time, needed no polling design of my own, and is the piece that actually addresses the case this issue was about — recovering the page after a cache wipe when nobody is printing. My suggested fix (refresh at the end ofprint_labels) would only have helped someone who prints.There is also a
restart_machinehook, which covers the second reproduction here exactly.Both are now implemented.
print_labelsis left alone deliberately: withAWAIT_RESULT_S=0the page sits atPRINTINGand the periodic refresh corrects it within a ping interval, whereas reading the retained topic immediately after dispatch would report the pre-print state and look like nothing happened.Lesson worth recording: I described a framework as lacking a hook after reading only the methods I already used.
dir(BaseDriver)would have shown it in one call.fix(status): refresh on restart and periodically, not only at init (#6)