Skip to content

Status is only refreshed at init, so it goes blank after any cache loss or machine restart #5

Closed

Description

@impuls42

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:

  1. 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 reads status=101, text='', because those are the defaults get_shared_state returns for missing keys.
  2. POST /api/machine/<pk>/restart/ clears the state and does not appear to call init_machine promptly. The machine reports initialized: True, is_driver_available: True, machine_errors: [] — healthy in every respect — while showing status=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

  1. impuls42 commented on Jul 30, 2026

    @impuls42
    MemberAuthor

    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:

    def ping_machines(self):
        """Ping all machines using this driver to check if they are online.
    
        This is called periodically by a background task if the setting
        'MACHINE_PING_ENABLED' is active."""

    MACHINE_PING_ENABLED defaults to True and is True on 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 of print_labels) would only have helped someone who prints.

    There is also a restart_machine hook, which covers the second reproduction here exactly.

    Both are now implemented. print_labels is left alone deliberately: with AWAIT_RESULT_S=0 the page sits at PRINTING and 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.

  2. added a commit that references this issue on Jul 30, 2026
    94dd547
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions