Task Queue & Rate Limiting
Relevant source files
The following files were used as context for generating this wiki page:
The Task Queue and Rate Limiting system is a core architectural component of Refined GitHub Projects designed to handle high-volume bulk operations against the GitHub GraphQL and REST APIs. Because GitHub enforces strict abuse detection and secondary rate limits (specifically for mutations), the extension centralizes all API-writing operations into a sequential background queue rather than firing concurrent requests.
The system ensures that bulk edits, duplications, and reordering operations proceed at a safe pace—typically with a 1-second delay between mutations—to prevent Personal Access Token (PAT) bans. It features real-time progress broadcasting, automatic exponential backoff on 403/429 errors, and concurrency controls that limit the number of active bulk processes.
Sources: README.md:167-172, CONTRIBUTING.md:13-17
Sequential Execution Architecture
All destructive or creative operations (mutations) must run through the sequential queue. The application strictly forbids the use of Promise.all() for GitHub API writes to avoid triggering 403 "Abuse" alerts.
Core Components
| Component | Description |
|---|---|
QueueTask | An interface defining a single unit of work with an id, optional detail string, and an asynchronous run function. |
processQueue | The primary execution engine that iterates through tasks, manages sleep delays, and handles retries. |
broadcastQueue | A helper function that sends queueStateUpdate messages to the UI for real-time progress tracking. |
Concurrency Guards | Logic to limit concurrent bulk operations (e.g., maximum of 3 concurrent processes). |
Sources: src/entries/background/handlers/bulk-handlers.ts:40-42, src/lib/tests/queue.test.ts:5-10, CONTRIBUTING.md:7-9
Operation Flow
The following diagram illustrates how a bulk update request moves from the content script to the background sequential processor.
Rate Limit Handling & Backoff
The system implements specific logic to handle GitHub's primary and secondary rate limits. When a request fails with a 403 (Abuse) or 429 (Too Many Requests) status code, the background worker enters a "paused" state.
Retry Logic
- Detection: The
withRateLimitRetrywrapper catches HTTP 403 and 429 errors. - Backoff: It extracts the
Retry-Afterheader (defaulting to 60 seconds if absent). - UI Feedback: A
queueStateUpdateis broadcasted withpaused: trueand theretryAfterduration, allowing the UI to show a countdown. - Resumption: After the sleep period, the system automatically attempts the request again (up to 3 attempts).
Task Processing Implementation
The processQueue function is responsible for iterating through the QueueTask[] array. It provides hooks for state changes and handles failures gracefully by collecting failedItems without halting the entire queue.
Implementation Details
- Sequentiality: It uses a standard
for...ofloop to ensure one task completes before the next begins. - State Tracking: It tracks
total,completed, andstatusstrings for each operation. - Cancellation: Supports
cancelQueue(processId)to stop processing if a user aborts an operation via the UI. - Wait Intervals: Standard operations (like bulk field updates or cloning) follow a
sleep(1000)pattern after each API call.
Sources: src/lib/tests/queue.test.ts:47-110, src/entries/background/handlers/bulk-handlers.ts:114-150, CONTRIBUTING.md:10-12
Code Snippet: Task Resolution and Execution
// From src/entries/background/handlers/bulk-handlers.ts
const tasks: QueueTask[] = resolvedItems.map(({ domId, issueNodeId }) => ({
id: `close-${domId}`,
run: async () => {
await gql(CLOSE_ISSUE, { issueId: issueNodeId, stateReason: data.reason })
await sleep(1000) // Mandatory rate-limit safety delay
},
}))
await processQueue(tasks, async (state) => {
await broadcastQueue({
total: state.total,
completed: state.completed,
status: `Closing items...`,
processId,
label,
}, tabId)
}, processId)
Sources: src/entries/background/handlers/bulk-handlers.ts:250-275
Concurrency Controls
To prevent multiple bulk operations from conflicting or overwhelming the connection, the background service worker maintains global state for different types of operations.
| Operation Type | Concurrency Manager | Logic |
|---|---|---|
| Bulk Updates | acquireBulk / releaseBulk | Ensures heavy field updates don't overlap. |
| Duplications | acquireDuplicate / releaseDuplicate | Limits "Deep Duplicate" operations which involve multiple sub-tasks (clone, label, attach, field sync). |
| Global Limit | isBulkFull() | Returns true if the maximum allowed concurrent operations (typically 3) is reached. |
Sources: src/entries/background/handlers/bulk-handlers.ts:61-64, src/entries/background/handlers/duplicate-handlers.ts:31-35, src/components/bulk/bulk-duplicate-modal.tsx:475-480
Conclusion
The Task Queue & Rate Limiting system serves as a reliability layer between the user's bulk actions and the GitHub API. By enforcing sequential execution and mandatory 1-second delays, it ensures that the extension remains compliant with GitHub's resource usage policies while providing a responsive, real-time feedback loop to the user via the Live Queue Tracker.