Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(coderd/externalauth/gitprovider): use conditional requests for GitHub JSON reads - #27628

Merged
johnstcn merged 1 commit into
coder:mainfrom
joshfree:josh/gitprovider-etag-conditional-requests
Jul 30, 2026
Merged

feat(coderd/externalauth/gitprovider): use conditional requests for GitHub JSON reads#27628
johnstcn merged 1 commit into
coder:mainfrom
joshfree:josh/gitprovider-etag-conditional-requests

Conversation

@joshfree

@joshfree joshfree commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #27627.

What

The chat diff-status gitsync worker polls open pull requests on a fixed 10s interval and re-downloads the full JSON body every tick, even when nothing changed, because the GitHub client never sends If-None-Match / ETag.

This adds a small, concurrency-safe, bounded in-memory ETag+body cache (coderd/externalauth/gitprovider/conditional.go) and wires it into githubProvider.decodeJSON. When an ETag is cached for a request, we send If-None-Match; on 304 Not Modified we decode the cached body; on 200 we cache {etag, body} when an ETag is present and the body is under a size cap.

Why

304 responses do not count against GitHub's primary rate limit, but full 200s do. Today every unchanged poll burns quota that the same token also needs for interactive Git and API operations, so busy instances can hit rate-limit errors and stalls elsewhere. Unchanged PRs now revalidate for free with no behavior change; only genuine changes transfer a body.

Details

  • Cache key = request URL + a hash of the token, so one token's response is never served under another; raw tokens are not retained.
  • Bounded by entry count (LRU eviction, default 2048) and per-body size (1 MiB) to cap memory.
  • Scope limited to the JSON reads through decodeJSON; the raw-diff path (fetchDiff, up to MaxDiffSize) is intentionally left out to avoid caching large bodies.

Tests

TestConditionalRequestReuse in github_test.go covers:

  • NotModifiedReusesCachedBody — a warm poll sends If-None-Match with the prior ETag and reuses the cached body on 304, yielding the same result with exactly two upstream requests.
  • DifferentTokenDoesNotShareCache — a different token never sends another token's cached ETag.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@github-actions github-actions Bot added the community Pull Requests and issues created by the community. label Jul 29, 2026
@joshfree

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

@joshfree

Copy link
Copy Markdown
Contributor Author

recheck

cdrci2 added a commit to coder/cla that referenced this pull request Jul 29, 2026
@joshfree joshfree changed the title feat(gitprovider): use conditional requests for GitHub JSON reads feat(coderd/externalauth/gitprovider): use conditional requests for GitHub JSON reads Jul 29, 2026
@ibetitsmike
ibetitsmike requested a review from johnstcn July 29, 2026 19:34

@johnstcn johnstcn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution!

EDIT: I see the Windows CI job is failing; this does not appear related to your changes. Looking.

@joshfree

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @johnstcn! 🙏

The two red checks look like unrelated CI flakes rather than anything from this (Go-only) change:

  • Storybook — the Storybook build itself completed successfully; the failure is in the pixel-storybook step (Configuration error). This PR touches no frontend files.
  • test-go-pg (windows-2022) — the runner failed during tooling setup (exit code 127, "agent was not installed"), so the Go tests never actually ran. The same test-go-pg suite passed on ubuntu and macOS.

Would you mind re-running those two jobs when you get a chance? Happy to rebase if you'd prefer. Thanks again!

@johnstcn

Copy link
Copy Markdown
Member

Would you mind re-running those two jobs when you get a chance? Happy to rebase if you'd prefer. Thanks again!

@joshfree Can you rebase on main to pick up dc1d6c3? 🤞 that this fixes the issue!

The chat-diff-status gitsync worker polls open pull requests on a short
interval, re-fetching full JSON bodies for pull requests that have not
changed. Add an in-memory, concurrency-safe LRU cache of ETags and
response bodies and issue `If-None-Match` on GitHub JSON reads so that
unchanged resources return `304 Not Modified` instead of a full body.
304 responses are cheaper and do not count against the primary REST
rate limit.

The cache is keyed by request URL plus a hash of the token so a cached
response for one token is never served under another, and it is bounded
by entry count and per-body size to cap memory use.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: 4959e1f9-f8e6-4e97-a487-f395a0123c79
@joshfree
joshfree force-pushed the josh/gitprovider-etag-conditional-requests branch from 688f25e to e9449ff Compare July 30, 2026 14:19
@johnstcn
johnstcn merged commit 2acfe7e into coder:main Jul 30, 2026
27 of 28 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

community Pull Requests and issues created by the community.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat diff-status worker re-downloads unchanged PRs instead of using conditional requests

2 participants