Skip to content

fix(pipeline)!: re-probe a tightened endpoint at the default budget - #1077

Open
ddeboer wants to merge 1 commit into
mainfrom
fix/adaptive-timeout-recovery
Open

ddeboer wants to merge 1 commit into
mainfrom
fix/adaptive-timeout-recovery

Conversation

@ddeboer

@ddeboer ddeboer commented Nov 14, 2026

Copy link
Copy Markdown
Member

Once AdaptiveTimeoutPolicy tightened an endpoint, it stayed tightened for as long as requests kept timing out, even when they were timing out at the tightened budget. On a healthy endpoint whose heavy queries take longer than tightenedMs, every heavy stage then failed until some cheap query happened to succeed. In the run in the issue, that took out ten stages.

The rule now: a timeout at the tightened budget doesn’t count toward tightening, because it says nothing about whether the endpoint is healthy. The policy re-probes instead, giving the next request on that endpoint defaultMs. If the probe succeeds, the endpoint relaxes. If it times out as well, the endpoint stays tightened, and the next timeout at the tightened budget schedules the next probe. Only one probe is handed out at a time; concurrent requests keep the tightened budget.

What this costs and buys:

  • A healthy-but-slow endpoint loses one request after tightening, not a run of stages. In the issue’s run, triples.rq would still time out at 10 s, but class-partition.rq would get the full 5 minutes and relax the endpoint.
  • An endpoint that keeps timing out at defaultMs now waits out the full budget on every other request rather than never again. That makes it slower to fast-fail than before, but it still takes about half the time it would without the policy.

To know which budget a timed-out request ran under, afterRequest now receives timeoutMs, the budget beforeRequest returned for that attempt. With requests in flight at the same time, the policy can’t reliably work that out from its own state or from durationMs (an upstream 504 can come back fast). That makes timeoutMs a required field of AfterRequestContext, hence the !.

The reference and the how-to guide describe the new rule.

Fixes #513

AdaptiveTimeoutPolicy kept an endpoint tightened as long as requests timed
out, including timeouts at the tightened budget itself. A healthy endpoint
whose heavy queries legitimately need longer than tightenedMs could then
only recover when some cheap query happened to succeed, losing every heavy
stage in between. A timeout at the tightened budget no longer counts toward
tightening; instead the next request runs at defaultMs. The endpoint relaxes
when that probe succeeds and stays tightened when it times out as well.

BREAKING CHANGE: AfterRequestContext has a required timeoutMs property:
the budget beforeRequest returned for the attempt. Code that calls
TimeoutPolicy.afterRequest itself must pass it.

This branch has not been deployed

No deployments
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.

AdaptiveTimeoutPolicy drops a block of stages from a healthy endpoint after one slow query

1 participant