Skip to content

tokens: cap discharge polling and make its timeout configurable - #286

Merged
dangra merged 1 commit into
mainfrom
discharge-poll-deadline
Aug 24, 2026
Merged

dangra merged 1 commit into
mainfrom
discharge-poll-deadline

Conversation

@dangra

@dangra dangra commented Aug 24, 2026 •

Copy link
Copy Markdown
Member

Fetching third party discharges ran under a hardcoded 30 second context while
the tp client polled on its default unbounded doubling backoff. Polls land at
t=0,1,3,7,15 and the next one is scheduled for t=31, so the client stops asking
for the second half of the time it was given; and 30 seconds was never much of
a budget for a discharge that waits on a person completing a login in their
browser. This caps the polling interval at a second and routes the timeout
through an UpdateOption, WithDischargeTimeout, with the default raised to
90 seconds.

Context

A discharge that needs user interaction only exists once the user finishes
authenticating at the third party. The client's entire job in between is to
notice when that happens, and an unbounded backoff makes it worst at exactly
the moment it matters most: the longer the person takes, the longer the
discharge sits ready and uncollected. Past the point where the interval
outgrows the remaining budget it is never collected at all, and Update
returns context deadline exceeded for a login that succeeded in good time.

The new default deserves an explicit justification. An interactive round trip
through an identity provider is realistically 10-30 seconds of human time
(page loads, an account chooser, a password manager, an MFA prompt, a redirect
chain), and the tail is much longer than the median. 30 seconds was sized like
an HTTP timeout rather than a human one. 90 covers the tail with room to spare
while staying bounded, and callers that know they are non-interactive can now
lower it instead of living with a constant. Anyone tuning it further should
know that flyctl's refreshDischargeTokens calls Tokens.Update twice, each
building its own context, so the user-visible worst case is about twice
whatever this value is.

Details

dischargePollingBackoff doubles from 100ms up to a 1 second cap and is passed
via tp.WithPollingBackoff. Polling a third party once a second while a person
is mid-login costs it very little, and it keeps the response to a finished
login immediate. Caller-supplied client options are now appended after these
defaults so they can still override them.

This is deliberately standalone. It uses only tp.WithPollingBackoff, public
since macaroon v0.3.0, so it needs no macaroon release to be effective; the
tests here pass against v0.3.0 as well as against macaroon main.
superfly/macaroon#46 makes the poll loop deadline-aware in general, which is
the better fix and helps every consumer of the library, but the two are
independent and either one alone closes the window this package cares about.

Fetching third party discharges ran under a hardcoded 30 second context
while the tp client polled on its default unbounded doubling backoff.
Both halves are wrong for a discharge that waits on a person completing
a login in their browser: polls land at t=0,1,3,7,15 and the next one is
scheduled for t=31, so nothing is polled for the second half of the
budget, and 30 seconds was never much of a budget for an interactive
round trip in the first place.

Cap the polling interval at a second, so the client notices a finished
login promptly however long the wait turns out to be, and route the
timeout through an UpdateOption with a 90 second default.
Copilot AI lite review requested due to automatic review settings August 24, 2026 22:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dangra
dangra merged commit 47a2e5b into main Aug 24, 2026
5 checks passed
@dangra
dangra deleted the discharge-poll-deadline branch August 24, 2026 22:21
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.

2 participants