fix(meteoalarm): the rate limit is daily, and the code assumed it was not - #297
Merged
Conversation
… not Running the live check produced what #293 was missing: HTTP/1.1 429 Too Many Requests X-RateLimit-Reset: 1788563205 {"error":"Daily rate limit exceeded. Please try again tomorrow."} Two things follow from "daily" that #293 got wrong. The backoff waited a flat fifteen minutes, which against a daily quota is about ninety-six retries a day, each spending a request that is already gone. It now reads `X-RateLimit-Reset` and waits until the named instant — capped at 25 hours so a nonsense value cannot disable the layer for a week, floored at "not in the past", and never shortening a cooldown already in force. The 120 s overlay cadence would have exhausted the quota daily on its own: 720 refreshes at up to `MAX_COUNTRIES` requests each. `EDR_MIN_INTERVAL` is five minutes, with the last answer reused while it still covers the screen. European warnings are issued hours ahead; five minutes is well inside anyone's resolution. `live_edr` no longer panics with a backtrace when the real failure is "you ran it today", and asserts a non-empty result — silently returning zero is exactly what the 429 did, and it looked like a quiet continent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What the API actually said
Running the live check produced the answer that was missing from #293:
Daily. #293 was written assuming a short window, and two things in it are wrong because of that.
1. The backoff ignored a header the server sends
It waited a flat fifteen minutes. Against a daily quota that is ~96 retries a day, every one spending a request from a budget that is already gone, and every one failing.
back_offnow readsX-RateLimit-Resetand waits until the named instant, falling back to an hour when the header is absent. Capped at 25 hours so a nonsense value cannot switch the layer off for a week, and floored at "not in the past" so a clock disagreement is not read as permission to hammer.It also no longer shortens a cooldown already in force — several requests fly at once, and the last one to land must not talk the others back into trying.
2. The refresh cadence would have exhausted the quota daily
The overlays refresh every 120 s. That is 720 refreshes a day, at up to
MAX_COUNTRIESrequests each — past any plausible daily allowance well before lunch. Nothing in #293 stopped that, and it would have shown up as "the feature works for ten minutes on the first day and never again".EDR_MIN_INTERVALis 5 minutes, with the last answer reused in between when it still covers the screen. Panning inside the fetched box is free; panning outside it is a question that was never asked and gets asked. European warnings are issued hours ahead and updated in tens of minutes, so five is well inside the resolution anyone can use.3. The live test says what happened
live_edrpanicked with anunwrapbacktrace. The ordinary way for it to fail is "you already ran it today", and it now says so, with the one-liner that shows when the quota returns.It also asserts the result is non-empty. Silently returning zero features is exactly what the 429 did for the first hour of #293, and it looked identical to a quiet continent.
Verification
cargo clippy --workspace --all-targets -- -D warnings— cleancargo test --workspace— pass, plus two tests:a_rate_limit_is_honoured_for_as_long_as_the_server_says— built from the real recorded 429:X-RateLimit-Reset: 1788563205against that response's owndateheader as epoch, asserting the full 86,400 s. Plus the no-header, unparseable, already-past and absurd-future cases.the_cached_answer_is_reused_only_where_it_actually_answers— inside the box, the same box, panned west, zoomed out northRUSTFLAGS='--cfg getrandom_backend="wasm_js"' cargo check --target wasm32-unknown-unknown -p hookecho --lib./scripts/shots/shoot.sh check— pass./scripts/web/build.sh— passlive_edrrun against the live API: fails cleanly with the quota message instead of a backtraceStill not verified end to end. The quota resets 2026-09-04 23:06 UTC. Until then no code can confirm the EDR path returns real features — which is the same gap #293 shipped with, now with a much better reason to believe the retry behaviour is sane.
wasm
4049134, unchanged — the whole EDR path iscfg(not(wasm32)). Budget unchanged at 4060000.🤖 Generated with Claude Code