SPB Git

fetch: HTTP/1.1 by default (h2 SEND_SETTINGS protocol errors), protocol errors classified transient; scheduler capacity 48/400

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Sep 13, 2026) parent 01ee6ea Browse files

2 changed files +8 −3

modified deploy/company-atlas.mld.json +2 −1
@@ -114,7 +114,8 @@
114 "CA_ADMIN_TOKEN": "{{ADMIN_TOKEN}}", 114 "CA_ADMIN_TOKEN": "{{ADMIN_TOKEN}}",
115 "CA_LLM_BASE_URL": "https://www.llm-api.io/v1", 115 "CA_LLM_BASE_URL": "https://www.llm-api.io/v1",
116 "CA_LLM_API_KEY": "{{LLM_KEY}}", 116 "CA_LLM_API_KEY": "{{LLM_KEY}}",
117− "CA_FETCH_CONCURRENCY": "32", 117+ "CA_FETCH_CONCURRENCY": "48",
118+ "CA_SCHEDULER_CLAIM_BATCH": "400",
118 "CA_ONBOARDING_CONCURRENCY": "12", 119 "CA_ONBOARDING_CONCURRENCY": "12",
119 "CA_DB_POOL_SIZE": "12", 120 "CA_DB_POOL_SIZE": "12",
120 "CA_DB_MAX_OVERFLOW": "12", 121 "CA_DB_MAX_OVERFLOW": "12",
modified src/companyatlas/fetch.py +6 −2
@@ -256,6 +256,8 @@ def classify_exception(exc: BaseException) -> FailureClass:
256 return exc.failure 256 return exc.failure
257 if isinstance(exc, httpx.ConnectTimeout | httpx.ReadTimeout | httpx.WriteTimeout | httpx.PoolTimeout | asyncio.TimeoutError | TimeoutError): 257 if isinstance(exc, httpx.ConnectTimeout | httpx.ReadTimeout | httpx.WriteTimeout | httpx.PoolTimeout | asyncio.TimeoutError | TimeoutError):
258 return FailureClass.TIMEOUT 258 return FailureClass.TIMEOUT
259+ if isinstance(exc, httpx.RemoteProtocolError | httpx.ProtocolError) or exc.__class__.__name__ in ("ProtocolError", "StreamReset", "ConnectionTerminated"):
260+ return FailureClass.TIMEOUT # transient transport-level protocol errors (h2 connection reuse, resets): retry policy, not a mystery
259 if isinstance(exc, httpx.ConnectError): 261 if isinstance(exc, httpx.ConnectError):
260 msg = str(exc).lower() 262 msg = str(exc).lower()
261 if "nodename" in msg or "name or service" in msg or "getaddrinfo" in msg or "temporary failure in name" in msg or "no address" in msg: 263 if "nodename" in msg or "name or service" in msg or "getaddrinfo" in msg or "temporary failure in name" in msg or "no address" in msg:
@@ -355,9 +357,11 @@ robots = RobotsCache()
355 357
356 358
357 class Fetcher: 359 class Fetcher:
358− """Shared httpx client (one per worker process). `get()` raises NotModified / FetchError / BlockedError.""" 360+ """Shared httpx client (one per worker process). `get()` raises NotModified / FetchError / BlockedError.
361+ HTTP/1.1 by default: h2 connection reuse against thousands of heterogeneous origins produced `ConnectionInputs.SEND_SETTINGS in state CLOSED`
362+ protocol errors (2026-09-13); HTTP/2 stays available per Fetcher (`http2=True`)."""
359 363
360− def __init__(self, *, timeout_s: float | None = None, headers: dict[str, str] | None = None, http2: bool = True, 364+ def __init__(self, *, timeout_s: float | None = None, headers: dict[str, str] | None = None, http2: bool = False,
361 max_connections: int | None = None): 365 max_connections: int | None = None):
362 self.timeout_s = timeout_s or settings.http_timeout_s 366 self.timeout_s = timeout_s or settings.http_timeout_s
363 self.headers = {"User-Agent": settings.user_agent, 367 self.headers = {"User-Agent": settings.user_agent,
364 368
Menu

Theme