Skip to content

feat(cache): serve stale metrics on GitHub rate limits#2439

Open
bhavyajain0810 wants to merge 1 commit into
Umbrella-io:mainfrom
bhavyajain0810:feat/github-rate-limit-cache-1930
Open

feat(cache): serve stale metrics on GitHub rate limits#2439
bhavyajain0810 wants to merge 1 commit into
Umbrella-io:mainfrom
bhavyajain0810:feat/github-rate-limit-cache-1930

Conversation

@bhavyajain0810

Copy link
Copy Markdown
Contributor

Summary

Adds stale-cache fallback support for GitHub-backed metrics so previously successful data can still be returned when GitHub temporarily rate-limits a refresh. The pinned repositories endpoint now uses the shared cache and centralized GitHub GraphQL handling while preserving authentication and non-rate-limit error behavior.

Closes #1930


Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that changes existing behavior)
  • 📝 Documentation update
  • ♻️ Refactor / code cleanup (no functional change)
  • ⚡ Performance improvement
  • 🔒 Security fix
  • 🧪 Tests only

What Changed

  • Extended src/lib/metrics-cache.ts with an optional stale-cache layer, configurable stale-grace period, and error predicate for controlled fallback.
  • Updated src/app/api/metrics/pinned-repos/route.ts to use withMetricsCache, cache-bypass handling, and the centralized githubGraphQL helper.
  • Added fallback behavior that serves stale pinned-repository data only when a GitHub rate-limit error prevents fresh data from loading.
  • Updated cache deletion so both the fresh entry and its corresponding stale entry are removed.
  • Added tests in test/metrics-cache.test.ts for stale fallback, unrelated errors, explicit cache bypass, and deletion of stale entries.

How to Test

  1. Run the focused lint checks:

    npx eslint src/lib/metrics-cache.ts src/app/api/metrics/pinned-repos/route.ts test/metrics-cache.test.ts test/pinned-repos.test.ts
  2. Run the relevant tests:

    npm test -- test/metrics-cache.test.ts test/pinned-repos.test.ts
  3. Run TypeScript validation:

    npm run type-check

Expected result:

  • ESLint completes without errors.
  • Both relevant test files pass: 23 tests passed.
  • tsc --noEmit completes without TypeScript errors.
  • A normal cache hit avoids a GitHub request.
  • After the fresh entry expires, a recognized GitHub rate-limit error returns the stale value.
  • Unrelated errors are still propagated instead of being hidden by stale data.
  • Explicit cache-bypass requests do not use fresh or stale cache fallback.

Checklist

  • Linked the related issue above
  • Self-reviewed my own diff
  • No unnecessary console.log, debug code, or commented-out blocks
  • npm run lint passes locally
  • No TypeScript errors (npm run type-check)
  • Added or updated tests where applicable
  • Updated documentation / comments if behavior changed

Additional Context

  • This is an internal API and caching change with no UI impact, so screenshots and accessibility testing are not applicable.
  • Stale fallback is opt-in and only activates when the supplied error predicate approves the failure.
  • Cache-bypass requests continue to force a fresh request and do not silently fall back to stale data.
  • Existing authentication failures and unrelated GitHub API failures continue to return their normal error responses.

@github-actions github-actions Bot added gssoc26 GSSoC 2026 contribution type:feature GSSoC type bonus: new feature type:testing GSSoC type bonus: tests (+10 pts) labels Jun 14, 2026
@github-actions

Copy link
Copy Markdown

GSSoC Label Checklist 🏷️

@Umbrella-io — please apply the appropriate labels before merging:

Difficulty (pick one):

  • level:beginner — 20 pts
  • level:intermediate — 35 pts
  • level:advanced — 55 pts
  • level:critical — 80 pts

Quality (optional):

  • quality:clean — ×1.2 multiplier
  • quality:exceptional — ×1.5 multiplier

Validation (required to score):

  • gssoc:approved — counts for points
  • gssoc:invalid / gssoc:spam / gssoc:ai-slop — does not score

Type labels (type:*) are auto-detected from files and title. Review and adjust if needed.
Points formula: (difficulty × quality_multiplier) + type_bonus

@github-actions github-actions Bot added type:bug GSSoC type bonus: bug fix type:performance GSSoC type bonus: performance (+15 pts) labels Jun 14, 2026
@bhavyajain0810

Copy link
Copy Markdown
Contributor Author

Hi @Priyanshu-byte-coder,

CI status note

The two failing Playwright checks appear unrelated to the changes in this PR.

E2E smoke test

The failing test is:

e2e/streak.spec.ts
[Streak E2E] streak widget shows the mocked longest streak value

Playwright reports a strict-mode violation because:

[aria-label="Your longest streak ever"]

matches two existing elements: the longest-streak card and its information button. The same failure occurred across retries, while the other 46 smoke tests passed.

Visual regression

The visual-regression job failed in these existing UI scenarios:

landing page full page screenshot in dark mode
public profile screenshot with deterministic mock data

The public-profile test timed out while waiting for the expected profile heading. Neither these pages nor their visual tests are modified by this PR.

This PR only changes:

  • src/lib/metrics-cache.ts
  • src/app/api/metrics/pinned-repos/route.ts
  • test/metrics-cache.test.ts

All relevant validation is passing, including build, lint, type-check, test coverage, dependency audit, environment security checks, and the focused cache and pinned-repository tests.

Could you please review or rerun these unrelated Playwright failures?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc26 GSSoC 2026 contribution type:bug GSSoC type bonus: bug fix type:feature GSSoC type bonus: new feature type:performance GSSoC type bonus: performance (+15 pts) type:testing GSSoC type bonus: tests (+10 pts)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Implement Redis-based Caching Layer for GitHub API Rate Limit Mitigation

1 participant