Skip to content

Stop traffic jobs from exhausting the GitHub token budget - #2

Merged
puppe1990 merged 1 commit into
mainfrom
fix/traffic-job-rate-limit
Sep 10, 2026
Merged

Stop traffic jobs from exhausting the GitHub token budget#2
puppe1990 merged 1 commit into
mainfrom
fix/traffic-job-rate-limit

Conversation

@puppe1990

Copy link
Copy Markdown
Owner

Problema

Em produção (github.gestaobem.com) havia 657 jobs SnapshotTraffic failed, todos com github: rate limited e attempts = 3/3 — ou seja, falha definitiva. No dia 07/09 foram 576 jobs e zero concluídos.

Causa raiz

  1. Amplificação por page viewwithTraffic enfileirava um job SnapshotTraffic{login} a cada requisição, sem dedup. Cada job percorre todos os repos em cache: 307 do usuário + 114 de 9 orgs = 421 repos × 2 chamadas (/traffic/views + /traffic/clones) ≈ 842 requests. Com 5.000/h, ~6 jobs esgotam a hora inteira.
  2. Hammering no rate limitSnapshotLogin continuava varrendo os ~420 repos depois do primeiro erro de rate limit (só guardava o first). Cada tentativa gastava ~45s disparando centenas de requests que só podiam falhar. A doc do GitHub avisa que insistir com a integração rate-limited pode resultar em ban.
  3. Retry incompatível com a janela — o backoff do worker é 2s/4s/8s, mas a janela do GitHub reseta em até 1 hora. O job era marcado failed definitivo muito antes da quota voltar.

Correção

  • O refresh de traffic passa a ser responsabilidade só do cron horário (SnapshotTraffic), que já existia. O path de request agora só preenche repos sem snapshot (fillMissingTraffic), o que já fazia.
  • SnapshotLogin para no primeiro erro em vez de continuar varrendo.
  • Rate limit encerra o run sem marcar como failed — a próxima execução agendada renova.

Testes

Quatro testes, escritos antes da implementação (TDD):

  • TestLoader_User_DoesNotEnqueueTrafficPerView — 3 page views não enfileiram nada (antes: 3 jobs)
  • TestLoader_SnapshotLogin_StopsOnFirstRateLimit — 25 repos rate-limited → 1 chamada (antes: 25)
  • TestPerformSnapshotTraffic_RateLimitedIsSkipped — rate limit não falha o job
  • TestClient_* existentes seguem cobrindo o mapeamento 403/remaining=0 → ErrRateLimited

make ci local: race tests, golangci-lint (0 issues) e Prettier verdes.

Observações

  • PerformRefreshCatalog tem o mesmo formato (erro → 3 tentativas em segundos), mas hoje não acumula falhas em produção; ficou fora do escopo.
  • Os 657 jobs failed foram limpos manualmente em produção após o deploy.

Production piled up 657 failed SnapshotTraffic jobs, all with
"github: rate limited", each burning its 3 attempts within seconds.

Three compounding causes:

- withTraffic enqueued a SnapshotTraffic job on every page view, with no
  dedup. Each job snapshots every cached repo (307 user + 114 org repos,
  two API calls each, ~842 requests), so a handful of page views spent
  the whole 5000/hour token budget.
- SnapshotLogin kept walking the remaining ~420 repos after the first
  rate-limit error, spending ~45s per attempt firing requests that could
  only fail. GitHub warns this can get an integration banned.
- The worker backs off 2s/4s/8s while GitHub's window resets in up to an
  hour, so the job was marked failed for good before the quota returned.

Traffic refresh already runs on the hourly SnapshotTraffic cron, so the
per-view enqueue was redundant: the request path now only fills repos
that have no snapshot yet. A rate limit ends the run without marking it
failed, leaving the next scheduled run to refresh it.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@puppe1990
puppe1990 merged commit 248c8eb into main Sep 10, 2026
4 checks passed
@puppe1990
puppe1990 deleted the fix/traffic-job-rate-limit branch September 10, 2026 19:04
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.

1 participant