Skip to content

fix(military): the relay and the seeder each burn a doomed OpenSky request to discover the other's 429 #6253

Description

@koala73

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

  1. 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.
  2. 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).
  3. 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.
  4. Preserve fail-open on every path — a Redis problem must never disable a data tier in
    either process.

Acceptance criteria

  • A 429 observed by the relay causes the seeder's next tick to skip without a request.
  • A 429 observed by the seeder causes the relay to skip without a request.
  • Both still fail OPEN on a Redis read error, a corrupt record, or an account mismatch.
  • The relay's existing in-process cooldown still works when Redis is unavailable.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions