feat(rotation): X-Boot-Reason: cold forces a resync regardless of schedule
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
Cold-boot polls (firmware sends X-Boot-Reason: cold on UNDEFINED wakeup cause) are treated as a deliberate "force a refresh" gesture from the user — unplug → replug to re-pull whatever the web app queued. Timer wakes still respect the wakeTimes schedule, so the schedule-gated semantics aren't undermined. Test: a cold-boot poll between scheduled wake times advances the rotation and writes a fresh DeviceImageHistory row, while an otherwise-identical timer-wake poll returns 304 without rotating. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -83,14 +83,18 @@ class DeviceImageController extends AbstractController
|
||||
// the second flush triggers a second publish to keep it accurate.
|
||||
$this->mercure->publishDevice((int) $device->getId(), $this->serializer->serialize($device));
|
||||
|
||||
// Locked image bypasses rotation entirely. Otherwise, only advance the
|
||||
// rotation when the device's configured schedule says it's due —
|
||||
// off-schedule polls (boot, button-mash, scheduler-driven status check)
|
||||
// hand back the device's current image without rotating, so the user
|
||||
// doesn't see surprise refreshes between configured wake times.
|
||||
// Locked image bypasses rotation entirely. Otherwise, advance only
|
||||
// when the device's configured schedule says it's due — except a
|
||||
// cold-boot poll (X-Boot-Reason: cold) is treated as a deliberate
|
||||
// user-driven force-refresh: unplug → replug → fresh rotation,
|
||||
// regardless of wakeTimes. Timer wakes stay schedule-gated, so users
|
||||
// don't see surprise refreshes between configured slots.
|
||||
$bootReason = strtolower((string) $request->headers->get('X-Boot-Reason', ''));
|
||||
$forceResync = ($bootReason === 'cold');
|
||||
|
||||
if ($device->getLockedImage() !== null) {
|
||||
$image = $device->getLockedImage();
|
||||
} elseif ($this->rotation->isDue($device)) {
|
||||
} elseif ($forceResync || $this->rotation->isDue($device)) {
|
||||
$image = $this->rotation->advance($device);
|
||||
} else {
|
||||
$image = $device->getCurrentImage();
|
||||
|
||||
Reference in New Issue
Block a user