Conversation
Add GitHub token resolution with fallback chain: explicit token → `gh auth token` → unauthenticated. Add `--jobs` / `-j` CLI flag to `install` and `update` commands for controlling concurrent downloads (default: 4).
Add GitHubRateLimiter that parses X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After headers. On 429 or rate-limit 403, sets a global pause shared across all concurrent downloads and retries once. Preemptively pauses when remaining hits 0. Integrates into GitHubClient via send_with_rate_limit, which wraps all HTTP methods with rate-limit awareness.
Add comment explaining deferred _max_concurrent usage and use lazy with_context() for error string allocation in send_with_rate_limit.
LNSD
left a comment
There was a problem hiding this comment.
The preemptive pause path can silently block for up to 60 minutes (unauthenticated) with no output after the initial warning.
The sequence:
- A 200 response arrives with X-RateLimit-Remaining: 0
- update_state sets paused_until to the reset timestamp (up to an hour away per https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api)
- User sees:
⚠ GitHub API rate limit exhausted, subsequent requests will be paused until reset - The current request completes normally
- The next request enters
wait_if_paused()->tokio::time::sleep(duration)with no further output
From the user's perspective (UX), the process hangs: no countdown, no spinner, no way to know how long the wait will be.
Suggestion: if Retry-After is absent or exceeds 60 seconds, fail immediately with an actionable error instead of sleeping. For unauthenticated users, the error should prompt them to provide a GITHUB_TOKEN to access the 5,000 requests/hour limit. Only sleep-and-retry for short pauses (≤60s) where waiting is reasonable.
Good suggestion, makes perfect sense. |
…locking Pauses exceeding 60s now return an actionable error prompting users to set GITHUB_TOKEN, instead of sleeping for up to an hour with no output.
| // Will be passed to DownloadManager for bounded-concurrent downloads | ||
| let _max_concurrent = jobs.unwrap_or(4); |
There was a problem hiding this comment.
We should avoid introducing dead code. Introducing dead code should be exceptional and justified (e.g., introducing a feature flag for a feature under development, establishing the foundations on which multiple features will depend, etc.). In general, for coordination purposes.
We should aim for self-contained PRs. Where all the changes have the same goal.
Could you remove the CLI options and this dead code, and include them in the downloads manager PR?
Summary
gh auth token→ unauthenticated--jobs/-jCLI flag toinstallandupdatecommands for controlling concurrent downloads (default: 4)GitHubRateLimiterthat parsesX-RateLimit-Remaining,X-RateLimit-Reset, andRetry-Afterheaders per GitHub REST API docsGitHubClientHTTP methods viasend_with_rate_limitGitHubClientcloneable for futureDownloadManagertask spawningChanges
Token resolution (
token.rs— new)resolve_github_token(): explicit →gh auth token→None--github-tokenvalues visible inps aux, prefer env var orghRate limiter (
rate_limiter.rs— new)GitHubRateLimiterwithtokio::sync::Mutex-protected statewait_if_paused(): blocking gate, drops lock before sleepingupdate_from_response()→update_state(): testable state machineRetry-Afterdefault: 60s per GitHub docs when header absentextend_pause(): only extends pauses, never shortensGitHub client (
github.rs— modified)send_with_rate_limit(): wraps all HTTP requests with rate-limit awareness and one retry on 429RateLimitederror variant with actionable user message#[derive(Clone)]onGitHubClient(cheap —reqwest::ClientandArc<GitHubRateLimiter>are both Arc-backed)CLI (
main.rs— modified)--jobs/-jflag oninstallandupdatecommandsTest plan