3.1 KiB
Ingestion System & Backoff Strategies
The ScholarIngestionService drives the primary data acquisition loop. Since Google Scholar utilizes heavy bot protection and rate limits, this package contains nuanced backoffs to protect user networks from automated IP bans.
Ingestion Overview
The underlying ingestion process:
- Receives an explicit request or background cron trigger to resolve a
scholar_profile_id. - Connects asynchronously using configured HTTPX adapters with strict browser headers.
- Downloads the paginated HTML feed for a user across multiple page iterations.
- Uses
regexand DOM-invariants (e.g.gsc_vcd_cib) to pull individual publication blocks.
Handling 429 Too Many Requests
Google Scholar aggressively throws HTTP 429 responses if multiple concurrent tabs or rapidly sequential commands query the same IP address for specific API endpoints (like citations?view_op=view_citation...).
Scholarr treats these distinct from random network timeouts.
- Network Error Retries: Handled via
ingestion_network_error_retrieswith a base backoff ofingestion_retry_backoff_seconds(Default 1.0s). - Rate Limit 429 Retries: When
ParseState.BLOCKED_OR_CAPTCHAcapturesblocked_http_429_rate_limited, the system applies a dedicated cooldown. It respectsingestion_rate_limit_retriesmultiplied byingestion_rate_limit_backoff_seconds(Default 30.0s). This prevents the pipeline from fatalizing a user's job completely, pausing operations seamlessly instead.
Publication Identifiers Loop
Once a publication is built, the gather_identifiers_for_publication module isolates keys explicitly.
- Local Parsing: Searches for direct identifiers within the HTML parameters (DOI patterns, arXiv regexes).
- API Fetching: Queries secondary bibliographic platforms sequentially:
export.arxiv.org/api/query(Queries by Title and Author strings).crossref.restfulAPIs (Queries by Title and Author strings).
These identifiers are accumulated in publication_identifiers instead of being bound as hard-coded properties, maximizing matching resilience in the automated Unpaywall PDF acquisition stage.
arXiv Request Controls
- Global throttle state: arXiv calls share
arxiv_runtime_stateso all workers respect one cooldown/interval clock. - Query cache: identical request parameters map to a stable fingerprint and are stored in
arxiv_query_cache_entries. - In-flight coalescing: duplicate concurrent misses join one outbound request instead of fan-out.
- Caller load-shedding: arXiv lookups are skipped when high-confidence DOI/arXiv evidence already exists, or when title quality is below threshold.
arXiv Observability Events
arxiv.request_scheduled: emitted before a gated request; includeswait_seconds,cooldown_remaining_seconds,source_path.arxiv.request_completed: emitted after response; includesstatus_code,wait_seconds,cooldown_remaining_seconds,source_path.arxiv.cooldown_activated: emitted when status429triggers cooldown.arxiv.cache_hit/arxiv.cache_miss: emitted on query cache lookup withsource_path.