Skip to content

Back off analyser polling while the queue is empty - #38

Closed
kasnder wants to merge 2 commits into
mainfrom
claude/analyser-idle-backoff
Closed

kasnder wants to merge 2 commits into
mainfrom
claude/analyser-idle-backoff

Conversation

@kasnder

@kasnder kasnder commented Oct 19, 2026

Copy link
Copy Markdown
Member

What

When there was no work, the analyser called /ping and /queue about every 30 seconds. Railway only sleeps a service after 5–10 minutes without outbound traffic, and responses to inbound requests count as outbound traffic, so the website never slept.

  • analyser/processQueue.sh: after an empty or failed /queue, wait IDLE_SLEEP_MIN (60 s), doubling each time up to IDLE_SLEEP_MAX (1800 s). The wait goes back to the minimum once an app is assigned. Every curl call now retries transient failures (connection refused, 5xx including Railway's cold-start 502) for up to 60 s. Retrying an upload whose first attempt did land just gets a 409 for the spent claim.
  • The analyser's last check-in was only held in memory (lastPing), so a woken process showed "Analyser offline" until the next ping. It is now also written to a one-row analyser_heartbeat table (migration 015) and read back once per process. A failed read is retried after a minute, and a failed write is logged without failing /ping.
  • Documented in analyser/.env.example and raspberry-pi-analyser.md.

Trade-off: an app requested while the queue is empty can wait up to IDLE_SLEEP_MAX (30 min by default) before the analyser picks it up. The Pi's checkout needs updating for the script change to take effect.

Testing

  • npm test: 165/165 pass, including the new test/analyserHeartbeat.test.js (the stored heartbeat is read once per process and /ping writes it).
  • Ran migration 015 (applied twice) and the heartbeat upsert/read against a local Postgres 16. The CHECK (id) constraint rejects a second row.
  • Ran the curl retry settings against a local server returning 502 twice and then 200 to a POST: it succeeded on the third attempt. A refused connection was retried.
  • Ran idle_backoff with small limits: 1, 2, 4, 5, 5 s.

CI will fail at the npm audit step until #37 merges; the advisories are unrelated to this change.

https://claude.ai/code/session_01Fi3H98SycMK13rrr8ySSU1


Generated by Claude Code

The analyser asked for work every 30 seconds even when there was none,
so the website never went quiet long enough for Railway to sleep it.
Double the wait between empty polls from IDLE_SLEEP_MIN (60s) up to
IDLE_SLEEP_MAX (1800s), resetting as soon as an app is assigned, and
retry transient curl failures for up to a minute so requests survive the
server waking up.

The analyser's last check-in was only held in memory, so a woken process
reported it offline until the next ping. Store it in an
analyser_heartbeat row and read it back once per process.

Claude-Session: https://claude.ai/code/session_01Fi3H98SycMK13rrr8ySSU1

kasnder commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

CI is red at the npm audit step only. npm test passes all 165 tests, including test/analyserHeartbeat.test.js.

The failure is not from this PR: it doesn't touch dependencies. The advisories (proxy-addr, brace-expansion, and braces via the dev dependency nodemon) were published after main last passed. #37 fixes them and its CI is green. To keep this PR separate, I haven't copied the lockfile change in here. Once #37 is merged I'll merge main into this branch so CI runs again. A re-run before then would fail the same way.


Generated by Claude Code

@kasnder
kasnder marked this pull request as ready for review October 20, 2026 07:41

kasnder commented Oct 20, 2026

Copy link
Copy Markdown
Member Author

Closing in favour of #39. That PR drops the polling entirely: the analyser waits for an ntfy wake-up or the next due time, and it keeps the stored heartbeat and curl retries from this PR.


Generated by Claude Code

@kasnder kasnder closed this Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants