Skip to content

A race condition in HttpScheduler can cause an expired preferred fallback host to be silently re-pinned when a long-running in-flight request succeeds after fallbackRetryTimeout has elapsed. #1205

@ttypic

Description

@ttypic

Steps to reproduce (logical sequence)

  1. Fallback host F succeeds and is stored as the preferred host via setPreferredHost(F, true) - timer starts.
  2. A new request A begins. getPreferredHost() returns F (not yet expired). candidateHost = F.
  3. Request A is in-flight against F for a duration that crosses fallbackRetryTimeout.
  4. A concurrent request B begins. getPreferredHost() finds the entry expired, clears it, and returns the primary host. Request B proceeds from primary — correct per RSC15f.
  5. Request A finishes successfully against F.
  6. HttpScheduler line 206 calls setPreferredHost(F, true). Because preferred.host is now null (cleared by step 4), isHost(F) returns false and the early-return guard is skipped.
    F is re-stored as the preferred host with a fresh timeout.

Expected behaviour

Once fallbackRetryTimeout has elapsed and the preference has been cleared, a successful response from the previously-preferred host should not re-establish that host as the preference. The
expiry event was authoritative; the in-flight request's outcome should not undo it.

Actual behaviour

The preferred host is restored with a new full fallbackRetryTimeout window, even though the system had already decided (correctly) to reset to primary for new requests.

┆Issue is synchronized with this Jira Task by Unito

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working. It's clear that this does need to be fixed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions