fix(signage): keep display updates, cron and metrics reliable - #526
Conversation
- Save ETag and Last-Modified only after a payload is applied, so a failed apply is fetched again. localStorage reads and writes are best effort, so a full store no longer blocks new content. - Cron searches step in UTC and match local fields. A repeated wall-clock time in the DST fall-back hour runs once. Searches are capped at 366 days. - Keep one schedule tick timer and clear it on destroy. - Record poll.last_success only when the backend answers. - Post metrics from a fresh object, catch errors and keep failed counts. - Prune completed schedule keys once their window has passed. - Do not release media that the cache sync already evicted.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
|
|
||
| /** Search limit in milliseconds, capped to `MAX_SEARCH_LIMIT_SECONDS` */ | ||
| function searchLimitMs(search_limit_in_seconds: number) { | ||
| return Math.min(search_limit_in_seconds, MAX_SEARCH_LIMIT_SECONDS) * 1000; |
There was a problem hiding this comment.
Long cron takeovers stop early
If a cron takeover has a play_period longer than 366 days, the new search cap can hide its start while the run is still active. For example, a February 29 run with a 368-day period is still active on March 2, 2025, but the player cannot find it and stops showing it. The search needs to cover the configured period.
There was a problem hiding this comment.
Fixed in 209e804. The search limit is now the requested period, capped at 10 years. To keep long searches cheap, both searches skip local days the cron cannot match (one check per day), and crons that can never run at any time of day return at once. Measured: a 10-year search for 0 0 31 2 * takes about 5 ms. Test: "finds a run that started more than a year ago" (0 0 29 2 *, 368-day period, checked on 2 Mar 2025).
There was a problem hiding this comment.
The remaining case is a deliberate limit, not an oversight. The search now covers the requested period, with a 10-year ceiling. Without a ceiling, a corrupt or extreme play_period (the manager sets no maximum) would make each schedule tick walk an unbounded number of days on low-power display hardware. A run is now missed only if its period exceeds 10 years and it started more than 10 years ago. For signage, a takeover that long is effectively permanent, and a background schedule is the right tool for it.
There was a problem hiding this comment.
That addresses the concern. Using the requested play period preserves long-running takeovers, while the 10-year ceiling is a reasonable defensive bound against an unbounded walk on display hardware. Given the stated behavior for periods beyond the ceiling and the fallback to background schedules for effectively permanent content, I’m withdrawing this finding.
- Cron searches cover the requested period, capped at 10 years, so a run longer than a year is still found. They skip local days the cron cannot match, so a long search costs one check per day. - Completed takeover runs are remembered until their window ends, not only while active. A playlist that briefly leaves the display no longer replays a finished takeover.
|
Deployment failed for project frontend-templates with the following error: Learn More: https://vercel.com/placeos?upgradeToPro=build-rate-limit |
The player could miss display updates, run cron takeovers at the wrong time around DST, and lose or misreport data over long uptime:
setDisplaycould start another 15 s tick chain that could not be stopped.poll.last_successadvanced while the backend was down.Changes
All in
signage.service.tsandcron-helpers.ts:last_successis set only when the backend answers (a 304 counts).Testing
nx test signage(427) andnx build signagepass.Notes
Independent of the other signage PRs from this review. Based on
develop.Changes made by Claude Opus 5.5 (1M context) in Claude Code, running in T3 Code.
🤖 Generated with Claude Code