Summary
The OpenSky quota is per account, but the two consumers that spend it keep entirely
separate 429 state:
Both authenticate with the same OPENSKY_CLIENT_ID. Neither reads the other's state, so
when one discovers the account is locked out, the other still spends a full doomed
round-trip to rediscover it — and keeps doing so on its own schedule for the rest of the
window.
Why it wasn't folded into #6241
#6241 was scoped to the seeder, and the relay's in-process cooldown already works for the
relay's own traffic. Cross-arming changes behaviour in a second, separately-deployed
service, so it deserves its own change and its own verification.
Proposed work
- Have the relay read
opensky:cooldown-until:v1 before its upstream call, in addition to
its in-process openskyGlobal429Until, and skip when the deadline is in the future.
- Have the relay write that key on a 429, using the same clamped-deadline rules the seeder
uses (OPENSKY_MAX_COOLDOWN_MS, fallback sized to the caller's own cadence).
- Keep the account fingerprint the seeder already stamps on the record
(openSkyAccountFingerprint()), so a credential rotation still can't make one process
inherit the other's stale lockout.
- Preserve fail-open on every path — a Redis problem must never disable a data tier in
either process.
Acceptance criteria
Related
Summary
The OpenSky quota is per account, but the two consumers that spend it keep entirely
separate 429 state:
scripts/ais-relay.cjs— long-lived process, holdsopenskyGlobal429Untilin a modulevariable (
scripts/ais-relay.cjs:8581).scripts/seed-military-flights.mjs— one-shot cron process, persists its deadline toopensky:cooldown-until:v1(added in fix(military): seeder ignores OpenSky 429 Retry-After — ~76 doomed requests per quota outage #6241 / PR fix(military): persist the OpenSky 429 cooldown so the seeder stops re-firing (#6241) #6252).Both authenticate with the same
OPENSKY_CLIENT_ID. Neither reads the other's state, sowhen one discovers the account is locked out, the other still spends a full doomed
round-trip to rediscover it — and keeps doing so on its own schedule for the rest of the
window.
Why it wasn't folded into #6241
#6241 was scoped to the seeder, and the relay's in-process cooldown already works for the
relay's own traffic. Cross-arming changes behaviour in a second, separately-deployed
service, so it deserves its own change and its own verification.
Proposed work
opensky:cooldown-until:v1before its upstream call, in addition toits in-process
openskyGlobal429Until, and skip when the deadline is in the future.uses (
OPENSKY_MAX_COOLDOWN_MS, fallback sized to the caller's own cadence).(
openSkyAccountFingerprint()), so a credential rotation still can't make one processinherit the other's stale lockout.
either process.
Acceptance criteria
Related