Repository navigation
tokens: cap discharge polling and make its timeout configurable - #286
Merged
Merged
Conversation
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.
This was referenced Aug 24, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fetching third party discharges ran under a hardcoded 30 second context while
the
tpclient polled on its default unbounded doubling backoff. Polls land att=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 to90 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
Updatereturns
context deadline exceededfor 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
refreshDischargeTokenscallsTokens.Updatetwice, eachbuilding its own context, so the user-visible worst case is about twice
whatever this value is.
Details
dischargePollingBackoffdoubles from 100ms up to a 1 second cap and is passedvia
tp.WithPollingBackoff. Polling a third party once a second while a personis 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, publicsince 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.