Skip to content

fix(backend): add retry logic and backoff for secondary rate limits in commit_files - #100

Merged
ankittroy-21 merged 2 commits into
ankittroy-21:ESSoC'26from
faizahmad-khan:fix/github-api-backoff-retry
Jul 21, 2026
Merged

fix(backend): add retry logic and backoff for secondary rate limits in commit_files#100
ankittroy-21 merged 2 commits into
ankittroy-21:ESSoC'26from
faizahmad-khan:fix/github-api-backoff-retry

Conversation

@faizahmad-khan

@faizahmad-khan faizahmad-khan commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

📋 Pull Request Description

To support the vision of maximizing GitHub contributions ("green dots"), GitPhone commits files sequentially (1 commit per file). However, executing rapid sequential mutating requests (POST/PUT/DELETE) can trigger GitHub's Secondary Rate Limit (Abuse) mechanisms during high-volume commits, returning 403 Forbidden errors and dropping remaining staged files.

This PR adds resilience to commit_files in backend/github_service.py:

  1. Proactive Throttling: Adds a 1-second delay (time.sleep(1)) between processing sequential file commits, adhering strictly to GitHub's integrator best practices.
  2. Exponential Backoff & Retry: Implements _execute_with_retry helper method to catch GithubException (status 403), parse the retry-after header if present, and retry up to 3 times before failing.
  3. Wrapped Mutating API Calls: Wraps repo.create_file, repo.update_file, and repo.delete_file calls with _execute_with_retry.

🔗 Related Issue

Closes #92

🏷️ PR Type

  • 🐛 Bug fix
  • ✨ New feature
  • 📝 Documentation
  • 🔧 Refactor / code quality
  • 🔒 Security fix
  • 🧪 Tests

✅ Checklist

  • I have commented on the issue before starting work
  • My branch is up to date with main
  • I have added the ECSoC26 label to this PR
  • Backend PRs: I ran ruff check backend/ locally and it passes
  • Extension PRs: I ran npx tsc --noEmit locally and it passes
  • I have NOT included any .env files, secrets, or tokens
  • I have written a clear PR description above

🧪 How to Test

  1. Stage multiple files (e.g. 5–10 files) via VS Code.
  2. Click "Commit All" to trigger sequential commits.
  3. Verify all files commit smoothly with 1s pauses in between, without triggering GitHub 403 Abuse rate limit errors.
  4. Verify ruff check backend/github_service.py passes cleanly.

📸 Screenshots (if UI changes)

N/A — backend resilience fix only.

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability for multi-file commits by retrying temporary GitHub API rate-limit and abuse responses.
    • Added pacing between file operations to reduce failed commits.
    • Ensured only successfully committed files are marked as committed.
    • Commit responses now report the accurate number of completed files.
  • New Features

    • Successful commits now create activity logs with commit details and notify the monitoring channel.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 87cdaf1a-8044-45d8-8e30-5a3d7c307898

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

GitHub file operations now retry matching rate-limit 403 responses and pace multi-file commits. The direct-commit route tracks successful file IDs, updates staged-file state, persists commit logs, sends monitoring notifications, and reports the committed count.

Changes

Commit flow

Layer / File(s) Summary
GitHub API retry and pacing
backend/github_service.py
GitHub create, update, and delete operations retry applicable rate-limit 403 responses, honor Retry-After when available, and pause between staged-file operations.
Direct commit tracking and notification
backend/routes/staged_files.py
POST /commit-direct processes committed IDs, updates staged-file status, records commit details, notifies the monitoring channel, and reports the successful commit count.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

Suggested labels: bug, backend

Suggested reviewers: ankittroy-21

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding retry logic and backoff for GitHub secondary rate limits in commit_files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ankittroy-21
ankittroy-21 changed the base branch from main to ESSoC'26 July 21, 2026 05:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/github_service.py`:
- Around line 180-184: The async commit_direct route synchronously invokes
commit_files, whose time.sleep and retry delays block the FastAPI event loop.
Update commit_direct to run the synchronous service invocation through
fastapi.concurrency.run_in_threadpool, preserving the existing commit_files
behavior and route response handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1d3622c7-33c4-4981-8bdb-a1a2548bef15

📥 Commits

Reviewing files that changed from the base of the PR and between a58cdb4 and ddd6aa8.

📒 Files selected for processing (2)
  • backend/github_service.py
  • backend/routes/staged_files.py

Comment thread backend/github_service.py
Comment on lines +180 to +184
for idx, staged in enumerate(staged_files):
if idx > 0:
# Proactively sleep 1s between file commits per GitHub's integrator best practices
time.sleep(1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Blocking call inside an async route.

The addition of time.sleep(1) (and the potential 60s sleep in _execute_with_retry) will block the thread. Since commit_files is called synchronously from the async def commit_direct route (in backend/routes/staged_files.py), this will block the FastAPI event loop, preventing the server from handling other concurrent requests on this worker.

Consider wrapping this synchronous service invocation in a thread pool using fastapi.concurrency.run_in_threadpool from the route, or changing the route definition to a synchronous def so FastAPI automatically runs it in a thread pool.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/github_service.py` around lines 180 - 184, The async commit_direct
route synchronously invokes commit_files, whose time.sleep and retry delays
block the FastAPI event loop. Update commit_direct to run the synchronous
service invocation through fastapi.concurrency.run_in_threadpool, preserving the
existing commit_files behavior and route response handling.

…ommit_direct

Avoid blocking the FastAPI async event loop during sequential commit sleeps and retry delays.
@ankittroy-21 ankittroy-21 added ECSoC26 Required on all scored PRs good-pr Bonus +15 XP (admin only) backend labels Jul 21, 2026
@ankittroy-21
ankittroy-21 merged commit 2c68d5b into ankittroy-21:ESSoC'26 Jul 21, 2026
1 check passed
@ecsoc-sentinel ecsoc-sentinel Bot added the ECSoC26-L1 Easy — 5 pts (auto by Sentinel) label Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend ECSoC26-L1 Easy — 5 pts (auto by Sentinel) ECSoC26 Required on all scored PRs good-pr Bonus +15 XP (admin only)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants