Fetcher: retry with backoff, per-site politeness, and concurrent feed refreshing #38
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The fetcher is single-attempt and single-threaded: each feed is fetched sequentially, every article page fetch runs one after another with no delay between same-site requests, and a failed fetch is never retried. Politeness delays without concurrency would just serialize everything further, so the three concerns need to land together.
The onestepoffthegrid WAF ban (see the issue-33 A/B and fixes) was triggered or worsened by exactly this shape: six same-host article pages hammered back-to-back with one identity. Politeness would likely have avoided tripping it at all; retries recover the rest.
Goal
Feeds and article pages are fetched with retry + exponential backoff on transient failures, a minimum interval between requests to the same host, and feeds refreshed concurrently so one slow or throttled site never blocks updates of the others — all with the SSRF guard intact on every request and hop.
Findings (current state)
fetch_all_feedsiterates feeds sequentially;_fetch_feed_responsemakes exactly one attempt per URL (no retry, noRetry-Afterhandling); article full-text fetches make two (browser identity, then extractor-identity retry — added in the WAF fix) with no delay between same-host hits._validate_feed_url+ per-hop re-validation) and_log_safemust survive the rework untouched.Plan of attack (design decided at implementation)
Retry-Afterwhen present. Non-transient 4xx (403/404) stay fail-fast; the article-page extractor-identity retry composes with this.httpx2.AsyncClient, or a bounded thread pool — decided during implementation), so per-host politeness delays never block unrelated feeds. SQLite writes remain on one side of the boundary.Retry-Afterhonouring, per-host isolation (a slow/blocked host does not delay another), guard preserved on every hop.Deliberately out of scope: trafilatura's downloader stays unused (see the fetcher discussion — SSRF guard and header control live in our fetcher).
No implementation until this gets a nod.
More thoughts on this: