Repository navigation
fix(clock): provision icons only once rediscover has judged the clock URL - #383
Conversation
… URL At boot, reapplySettings restores the weather and Pomodoro slices before the clock URL override (clock is registered last), and their after hooks start an icon provisioning job. That job listed /ICONS on the file URL (192.168.0.14 on the live server, now the knob) before the override was restored and before rediscover had judged it, logged "device list failed" and never retried. reapplySettings now holds icon provisioning; boot provisions from StartWeather after initDeviceDiscovery, and /admin/reload provisions explicitly after its reapply, as it already does for the boot ping. A rediscover swap after boot moved the clock without re-running the per-clock one-shots, so a clock found by the 30 s watch never got its icons or boot-ping script until a config change or restart. A swap now re-runs icon provisioning and ensureBootPingScript next to the existing capabilities refresh. Closes #382
Codex review (read-only, static)No blockers. Should-fix: Nit: Nit: Checked, nothing found:
|
Independent review: #383Verdict: no blockers. The fix is correct for #382. I'd fix the four should-fix items before merging. What I checked: should-fix
nit
STYLE / docs
|
Review of #383: - reapplySettings defers releasing iconHold and the clock-sync pause, so a panicking settings hook (recovered by net/http on /admin/reload) can no longer leave icon provisioning silently off for the process. - rediscoverClock no longer provisions. initDeviceDiscovery and the watch's swap branch start icons and the boot-ping install on App.clockJobs (renamed from iconJobs) after rediscover returns, so a clock that stalls script requests holds neither deviceRediscoverMu, the HTTP listener at boot, nor the clock_rediscovered republish. - Boot provisioning is explicit in initDeviceDiscovery, not a side effect of StartWeather, and runs once: the StartWeather icon run and the main boot-ping worker are gone. Shutdown waits for clockJobs. - Tests pin the reload provisioning call, boot provisioning on a reachable clock, the boot-ping install with its callback URL on a moved clock, and the panic release. - ARCHITECTURE names the real /api/v1/files endpoints. Refs #382
Review replies: fixed in 51834b2Fail-first means the test was run against a178815, the commit before the fix. Opus #1 / Codex nit (iconHold not released on panic): fixed.
Opus #2 / Codex should-fix (boot ping sync under
Opus #3 (reload call untested): fixed.
Opus #4 + #5 (boot provisioning relied on
Opus #6 (dropped-while-held flag): not done. Running the dropped job on release would fire at boot as soon as Opus #7 (PUT Opus #8 (ARCHITECTURE endpoints): fixed. The paragraph now says Codex nit (only the uninstall path covered): fixed. Checks: |
Re-review of 51834b2 (on top of a178815)Verdict: clean. No blockers and no should-fix items. Two nits, neither needs to block the merge. Prior should-fixes: all fixedI copied the new tests onto a178815's code, with
Boot coverage after moving provisioning into
|
Closes #382
Summary
/ICONSlist did not come from rediscover being slow.reapplySettingsrestores stored slices in registration order. Weather and Pomodoro come beforeclock(the URL override), and theirafterhooks callprovisionIconsInBackground. That job dialled the file URL (192.168.0.14, now the knob) while the override (.16) was still being restored, beforeinitDeviceDiscoveryran. The ESP32's slow RST explains the ~100 ms gap before the warning. There is noclock auto-discoveredline, and caps were fetched fresh from the right URL right after.Design (updated after review, 51834b2)
App.iconHold:reapplySettingsholds icon provisioning while it restores slices, so theirafterhooks can't hit a URL that rediscover hasn't judged. The hold and the clock-sync pause are both released bydefer./admin/reloadprovisions explicitly after its reapply.provisionClockInBackground(ctx)starts icon provisioning and the boot-ping install onApp.clockJobs, and shutdown waits for them. There are two callers:initDeviceDiscovery, after the boot rediscover. This is the only boot run: theStartWeathericon call andmain's boot-ping worker are removed.StartDeviceWatch, on a swap, afterrediscoverClockreturns.rediscoverClockitself does no provisioning, so it never waits on a slow clock while holdingdeviceRediscoverMu.Test plan
cmd/ember/icon_provision_clock_test.gouses realclockPublisherand two httptest clocks (stale = 404 everything, moved = awtrix-ng fingerprint):TestRediscoverClock_ProvisionsIconsOnMovedClock: swap → moved clock gets the/ICONSlist, 2 uploads and the boot-ping script GET; stale gets none.TestBootSequence_ProvisionsIconsOnlyAfterRediscover: stored weather slice, stale file URL →reapplySettings→initDeviceDiscovery→ no/ICONSrequest to stale, uploads land on the rediscovered clock.icon provision: device list failedwarning against the stale URL.gofmt -l .clean,go vet ./...clean,go test -race ./...all ok.Audit: boot-time clock I/O before rediscover
refreshCapabilitiesruns insideinitDeviceDiscoveryafterrediscoverClock. In the live log the 21.032device capabilities cachedwas a fresh fetch from the judged URL. There is no persistent cache, anda.capsis in-memory only.initPomodoro,migrateClockConfig, other reapplyafterhooks (nudgePomo): no clock I/O. Coordinator sends are queued and published only afterStartCoordinator.ClearIndicators,ensureBootPingScript, coordinator, brightness, weather workers: all start afterinitDeviceDiscovery.Docs: ARCHITECTURE (icon provisioning, discovery swap) and RUNBOOK (self-healing) updated.