fix(simulation): retry temporary provider proxy failures

This commit is contained in:
DCCONSTRUCTIONS
2026-08-29 16:01:28 +03:00
parent 4b487e367f
commit e6df8cb264
2 changed files with 32 additions and 1 deletions
@@ -36,6 +36,7 @@ IMAGE_DIGEST_PATTERN: Final = re.compile(r"^sha256:[a-f0-9]{64}$")
DEFAULT_CHUNK_BYTES: Final = 8 * 1024 * 1024
MAX_JSON_RESPONSE_BYTES: Final = 32 * 1024 * 1024
MAX_RETRIES: Final = 3
RETRYABLE_PROVIDER_STATUS_CODES: Final = {502, 503, 504}
DEFAULT_INGEST_TIMEOUT_SECONDS: Final = 30 * 60.0
@@ -899,7 +900,10 @@ def _validate_runtime_provenance(document: Mapping[str, object]) -> None:
def _unavailable(message: str, error: httpx.HTTPError) -> GaussianPipelineGatewayError:
if isinstance(error, httpx.TransportError):
if isinstance(error, httpx.TransportError) or (
isinstance(error, httpx.HTTPStatusError)
and error.response.status_code in RETRYABLE_PROVIDER_STATUS_CODES
):
return GaussianPipelineUnavailableError(message)
return GaussianPipelineGatewayError(message)
@@ -922,4 +926,6 @@ def _provider_rejection(response: httpx.Response) -> GaussianPipelineGatewayErro
message = f"Gaussian provider rejected request (HTTP {response.status_code})"
if detail is not None:
message = f"{message}: {detail}"
if response.status_code in RETRYABLE_PROVIDER_STATUS_CODES:
return GaussianPipelineUnavailableError(message)
return GaussianPipelineGatewayError(message)
+25
View File
@@ -14,6 +14,7 @@ from k1link.simulation.gaussian_pipeline_gateway import (
GaussianPipelineGateway,
GaussianPipelineGatewayError,
GaussianPipelineIntegrityError,
GaussianPipelineUnavailableError,
_discover_bundle_members,
)
@@ -256,6 +257,30 @@ def test_gateway_surfaces_bounded_provider_rejection_detail(tmp_path: Path) -> N
))
@pytest.mark.parametrize("status_code", [502, 503, 504])
def test_gateway_classifies_temporary_provider_proxy_failures_as_unavailable(
tmp_path: Path,
status_code: int,
) -> None:
with (
GaussianPipelineGateway(
"http://gaussian.test",
_token_file(tmp_path),
transport=httpx.MockTransport(
lambda _request: httpx.Response(
status_code,
json={"error": "provider_unavailable"},
)
),
) as gateway,
pytest.raises(
GaussianPipelineUnavailableError,
match=rf"HTTP {status_code}.*provider_unavailable",
),
):
gateway.capabilities()
def test_gateway_rejects_incomplete_lcc_bundle(tmp_path: Path) -> None:
bundle = tmp_path / "bundle"
bundle.mkdir()