ilidemi opened a new pull request, #2265:
URL: https://github.com/apache/iceberg-go/pull/2265
Fixes #2264.
## Summary
```diff
AuthHeaderWithContext(ctx)
if ctx already done → return ctx.Err()
- tokenSource.Token() // blocks until the refresh client's
Timeout
+ select
+ ctx done → return ctx.Err()
+ shared refresh → header // one Token() in flight per manager
```
A `singleflight.Group` on `Oauth2AuthManager` dedupes `Token()` across
concurrent callers. A caller that stops waiting leaves nothing queued behind
the shared call, so a stalled endpoint sees one request however many callers
gave up on it. The refresh keeps running on the token-refresh client, still
bounded by its `Timeout`, and later callers reuse its result. `AuthHeader` goes
through the same group so both entry points share one refresh. The error
mapping in `authHeader` is unchanged; it now receives singleflight's untyped
result.
Completes the context threading suggested earlier in the #1655 review
(https://github.com/apache/iceberg-go/pull/1655#discussion_r3737958963). That
review warned that wrapping the context-free call in a goroutine only relocates
the leak; the singleflight is the answer, since there is at most one such
goroutine per manager and it terminates with the client `Timeout`.
## Evidence
- **Before:** with the select removed,
`TestOauth2AuthManager_AuthHeaderWithContext_CallerDeadline` hangs until `go
test` kills it (`panic: test timed out after 15s`); with a per-caller
singleflight key, `TestOauth2AuthManager_AuthHeaderWithContext_SharesRefresh`
fails with `waiting callers must share one refresh`, expected 1 `Token()` call,
got 5.
**After:** `go test -count=3 -race -run Oauth2AuthManager ./catalog/rest/`
→ `ok 2.3s`; full `./catalog/rest/` under `-race` → `ok 5.7s`; `golangci-lint`
→ 0 issues.
## Merge Danger
**Door:** two-way
Revert restores the previous synchronous behavior; no persisted state or
wire format involved.
**Blast Radius:** REST catalog OAuth callers
Two observable changes. `AuthHeaderWithContext` can now return `ctx.Err()`
for a caller whose context ends during a refresh, where it previously blocked
and then returned the refresh error. Callers joining an in-flight refresh share
its outcome, including its error, instead of each running their own attempt.
Static-token and cached-token paths are unchanged apart from passing through
singleflight.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]