fix(crawler): treat HTTP 429 as rate-limit condition with cooldown backoff - #3642
fix(crawler): treat HTTP 429 as rate-limit condition with cooldown backoff#3642SoloDevAbu wants to merge 3 commits into
Conversation
barjin
left a comment
There was a problem hiding this comment.
Thank you for your contribution @SoloDevAbu .
I believe we should match the implementation of this feature with the similar feature in crawlee-python. Please see the PR here.
Below, I added a few comments (those might be irrelevant to the Python-inspired implementation).
| /** | ||
| * How long to wait before retrying a request that failed with a rate limit error (HTTP 429). | ||
| * This value will only be used if the server does not return a `Retry-After` header. | ||
| * @default 60 | ||
| */ | ||
| rateLimitCooldownSecs?: number; |
There was a problem hiding this comment.
Note that for backward compatibility, we should retry immediately. This change in default behaviour might make some users' workflows run much longer.
|
|
||
| if (error instanceof RateLimitError) { | ||
| const delayMillis = error.delayMillis || this.rateLimitCooldownMillis; | ||
| await sleep(delayMillis); |
There was a problem hiding this comment.
What happens if delayMillis is longer than internalTimeoutMillis? Won't the request fail anyway with a timeout?
barjin
left a comment
There was a problem hiding this comment.
As described in the previous review, we want to implement something like the new Python ThrottlingRequestManager to keep both versions aligned.
Also, the implementation in this PR would likely not work well with Crawlee's autoscaling. We do not want the waiting requests to block the execution of other requests - these should preferably "skip the line". With the current impl, we might just get stuck waiting for the delay to elapse, with other (valid) requests just waiting idle in the RequestQueue.
For these reasons, I'll be closing this PR now. Feel free to open a new one following apify/crawlee-python#1762 if you feel like it.
Thank you!
Fix: HTTP 429 treated as rate-limit condition with cooldown backoff
Closes #3623
Changes
RateLimitErrorto represent retriable rate-limit failures with optional delay metadatarateLimitCooldownSecs(BasicCrawleroption, default60) as fallback wait time for429withoutRetry-AfterBasicCrawlerto:RateLimitError.delayMillis(or fallback cooldown)session.markBad()for rate-limit retriesRateLimitErroron429and parseRetry-After429from default blocked status codes so session blocking remains focused on true block/auth statuses (401,403)Test Coverage
Test updates/additions validate:
429withRetry-Afterdelays retry appropriately429withoutRetry-Afteruses fallback cooldown429429delayed-retry behavior