Skip to content

fix(meteoalarm): the rate limit is daily, and the code assumed it was not - #297

Merged
d4vid87 merged 1 commit into
mainfrom
fix/meteoalarm-daily-quota
Sep 3, 2026
Merged

fix(meteoalarm): the rate limit is daily, and the code assumed it was not#297
d4vid87 merged 1 commit into
mainfrom
fix/meteoalarm-daily-quota

Conversation

@d4vid87

@d4vid87 d4vid87 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

What the API actually said

Running the live check produced the answer that was missing from #293:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Reset: 1788563205
{"error":"Daily rate limit exceeded. Please try again tomorrow."}

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_off now reads X-RateLimit-Reset and 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_COUNTRIES requests 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_INTERVAL is 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_edr panicked with an unwrap backtrace. 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 — clean
  • cargo 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: 1788563205 against that response's own date header 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 north
  • RUSTFLAGS='--cfg getrandom_backend="wasm_js"' cargo check --target wasm32-unknown-unknown -p hookecho --lib
  • ./scripts/shots/shoot.sh check — pass
  • ./scripts/web/build.sh — pass
  • live_edr run against the live API: fails cleanly with the quota message instead of a backtrace

Still 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 is cfg(not(wasm32)). Budget unchanged at 4060000.

🤖 Generated with Claude Code

… 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>
@d4vid87
d4vid87 merged commit 3c57d88 into main Sep 3, 2026
6 checks passed
@d4vid87
d4vid87 deleted the fix/meteoalarm-daily-quota branch September 3, 2026 23:15
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.

1 participant