mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-08-11 00:30:12 -04:00
Selecting an item hands any keep-warm hold on its printer over to the preheat
pin: `_sweep_keep_warm` drops the `_keep_warm` entry and records "bed" instead,
on the promise that `_dispatch_one` will unwind it on any non-success exit. Two
of that function's exits never reached the `finally` that keeps the promise --
the claim failure returns before the `try` opens, and the vanished-row return
sat inside it but left `item_printer_id` at None, which the rollback guards on.
Either one left the bed hot with nothing tracking it. The keep-warm entry was
already gone, so the max-duration cap no longer applied and `_release_keep_warm`
had nothing to act on; if the cancelled item was that printer's last pending
one, the printer also dropped out of the candidate set, and nothing would ever
switch the bed off. Reachable whenever a cancel or delete lands between
selection and the claim -- narrow, but the outcome is exactly what the cap was
added to prevent.
`_dispatch_one` now takes the printer it was selected for. `_launch_uploads`
already had it (it stores the same value in `_inflight`), so nothing new is
plumbed, and the parameter is optional so the tests that call `_dispatch_one`
directly keep their existing behaviour.
Two pieces of hardening found while tracing that:
* The rollback switched the bed off unconditionally, where the keep-warm
release deliberately checks first that firmware still reports the target it
set. It now records what it pinned and declines when someone else owns the
bed. Every uncertain case still switches off -- no recorded target, or a
status that cannot be read -- because a bed left hot with no owner is the
worse failure, and this runs in a `finally` where raising would mask the
real exception. That is why the status read is factored out into a total
helper returning None for "no evidence" rather than 0.
* `_apply_keep_warm` ran unguarded between selection and `_launch_uploads`, so
anything raising there discarded the tick's selections, computed AMS
mappings included, and on a persistent fault stopped the queue dispatching
altogether. Wrapped, for the same reason the deficit check is: an auxiliary
comfort feature must never wedge dispatch.
Also documents why the max-duration check sits behind the FINISH and client
guards rather than ahead of them, since the ordering looks like a hole and is
not: with no client there is no M140 to send and the elapsed check fires on the
first tick after the printer returns, and leaving FINISH means the plate was
cleared, which routes the printer to `_release_keep_warm` instead. The invariant
to preserve if that is ever reordered is that every path out of an engaged hold
ends in a bed-off.
Six tests: the handover recording its target, both early returns releasing, a
call with no printer id staying a no-op, the reassigned-bed skip, the matching
and unreadable cases switching off, and eviction on deregistration.
|
||
|---|---|---|
| .. | ||
| assets | ||
| fonts | ||
| icons | ||
| img | ||
| index.html | ||
| manifest.json | ||
| spoolbuddy_logo_dark.png | ||
| sw-register.js | ||
| sw.js | ||
| vite.svg | ||