From fc76ce33916aa3f7c36c1fcdb80b700849f0baa6 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Fri, 10 Jul 2026 05:11:57 +0000 Subject: [PATCH 1/4] CI: retry transient HTTP timeouts in Studio smoke probes The post() helper in the Studio inference smoke workflows does a single urlopen with a 240s timeout against the local Studio server. On shared runners this sporadically hits TimeoutError while the server is stalled, failing the whole job for a transport hiccup; the same flake has recurred across unrelated PRs on Linux and Windows (JSON/images and tool-calling jobs) and passes on rerun. Retry the probe up to 3 times on transport-level failures only (TimeoutError, ConnectionError, non-HTTP URLError), 15s apart. HTTP status errors still surface immediately, so genuine server failures are unaffected. post_sse() is left unchanged: it has a 600s budget and has not flaked. --- .github/workflows/studio-inference-smoke.yml | 34 ++++++++++++++++--- .../workflows/studio-mac-inference-smoke.yml | 34 ++++++++++++++++--- .../studio-windows-inference-smoke.yml | 34 ++++++++++++++++--- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/.github/workflows/studio-inference-smoke.yml b/.github/workflows/studio-inference-smoke.yml index aebf90380a..ce0c6f6ba4 100644 --- a/.github/workflows/studio-inference-smoke.yml +++ b/.github/workflows/studio-inference-smoke.yml @@ -444,6 +444,8 @@ jobs: python - <<'PY' import json import os + import time + import urllib.error import urllib.request BASE = os.environ["BASE_URL"] @@ -464,8 +466,19 @@ jobs: "Content-Type": "application/json", }, ) - with urllib.request.urlopen(req, timeout = timeout) as resp: - return resp.status, json.loads(resp.read().decode()) + # Shared CI runners stall sporadically, so retry transport-level + # failures only; HTTP status errors surface immediately. + for attempt in range(3): + try: + with urllib.request.urlopen(req, timeout = timeout) as resp: + return resp.status, json.loads(resp.read().decode()) + except urllib.error.HTTPError: + raise + except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: + if attempt == 2: + raise + print(f"[retry] {path}: {exc!r}", flush = True) + time.sleep(15) def post_sse(path, body, *, timeout = 600): """POST a streaming request and accumulate the assistant @@ -938,6 +951,8 @@ jobs: import base64 import json import os + import time + import urllib.error import urllib.request from openai import OpenAI from anthropic import Anthropic @@ -956,8 +971,19 @@ jobs: "Content-Type": "application/json", }, ) - with urllib.request.urlopen(req, timeout = timeout) as resp: - return resp.status, json.loads(resp.read().decode()) + # Shared CI runners stall sporadically, so retry transport-level + # failures only; HTTP status errors surface immediately. + for attempt in range(3): + try: + with urllib.request.urlopen(req, timeout = timeout) as resp: + return resp.status, json.loads(resp.read().decode()) + except urllib.error.HTTPError: + raise + except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: + if attempt == 2: + raise + print(f"[retry] {path}: {exc!r}", flush = True) + time.sleep(15) # ── 1. response_format = json_object (JSON mode) ───────────── # llama.cpp's HTTP server supports OpenAI-compatible JSON diff --git a/.github/workflows/studio-mac-inference-smoke.yml b/.github/workflows/studio-mac-inference-smoke.yml index d562294d42..d9d98e3a16 100644 --- a/.github/workflows/studio-mac-inference-smoke.yml +++ b/.github/workflows/studio-mac-inference-smoke.yml @@ -430,6 +430,8 @@ jobs: python - <<'PY' import json import os + import time + import urllib.error import urllib.request BASE = os.environ["BASE_URL"] @@ -450,8 +452,19 @@ jobs: "Content-Type": "application/json", }, ) - with urllib.request.urlopen(req, timeout = timeout) as resp: - return resp.status, json.loads(resp.read().decode()) + # Shared CI runners stall sporadically, so retry transport-level + # failures only; HTTP status errors surface immediately. + for attempt in range(3): + try: + with urllib.request.urlopen(req, timeout = timeout) as resp: + return resp.status, json.loads(resp.read().decode()) + except urllib.error.HTTPError: + raise + except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: + if attempt == 2: + raise + print(f"[retry] {path}: {exc!r}", flush = True) + time.sleep(15) def post_sse(path, body, *, timeout = 600): """POST a streaming request and accumulate the assistant @@ -825,6 +838,8 @@ jobs: import base64 import json import os + import time + import urllib.error import urllib.request from openai import OpenAI from anthropic import Anthropic @@ -848,8 +863,19 @@ jobs: "Content-Type": "application/json", }, ) - with urllib.request.urlopen(req, timeout = timeout) as resp: - return resp.status, json.loads(resp.read().decode()) + # Shared CI runners stall sporadically, so retry transport-level + # failures only; HTTP status errors surface immediately. + for attempt in range(3): + try: + with urllib.request.urlopen(req, timeout = timeout) as resp: + return resp.status, json.loads(resp.read().decode()) + except urllib.error.HTTPError: + raise + except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: + if attempt == 2: + raise + print(f"[retry] {path}: {exc!r}", flush = True) + time.sleep(15) # ── 1. response_format = json_object (JSON mode) ───────────── # llama.cpp's HTTP server supports OpenAI-compatible JSON diff --git a/.github/workflows/studio-windows-inference-smoke.yml b/.github/workflows/studio-windows-inference-smoke.yml index dbb0f9ea6f..00cf9adcf1 100644 --- a/.github/workflows/studio-windows-inference-smoke.yml +++ b/.github/workflows/studio-windows-inference-smoke.yml @@ -634,6 +634,8 @@ jobs: python - <<'PY' import json import os + import time + import urllib.error import urllib.request BASE = os.environ["BASE_URL"] @@ -656,8 +658,19 @@ jobs: "Content-Type": "application/json", }, ) - with urllib.request.urlopen(req, timeout = timeout) as resp: - return resp.status, json.loads(resp.read().decode()) + # Shared CI runners stall sporadically, so retry transport-level + # failures only; HTTP status errors surface immediately. + for attempt in range(3): + try: + with urllib.request.urlopen(req, timeout = timeout) as resp: + return resp.status, json.loads(resp.read().decode()) + except urllib.error.HTTPError: + raise + except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: + if attempt == 2: + raise + print(f"[retry] {path}: {exc!r}", flush = True) + time.sleep(15) def post_sse(path, body, *, timeout = 600): body = {**body, "stream": True} @@ -1063,6 +1076,8 @@ jobs: import base64 import json import os + import time + import urllib.error import urllib.request from openai import OpenAI from anthropic import Anthropic @@ -1082,8 +1097,19 @@ jobs: "Content-Type": "application/json", }, ) - with urllib.request.urlopen(req, timeout = timeout) as resp: - return resp.status, json.loads(resp.read().decode()) + # Shared CI runners stall sporadically, so retry transport-level + # failures only; HTTP status errors surface immediately. + for attempt in range(3): + try: + with urllib.request.urlopen(req, timeout = timeout) as resp: + return resp.status, json.loads(resp.read().decode()) + except urllib.error.HTTPError: + raise + except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: + if attempt == 2: + raise + print(f"[retry] {path}: {exc!r}", flush = True) + time.sleep(15) # ── 1. response_format = json_object (JSON mode) ───────────── status, data = post("/v1/chat/completions", { From b4c02db66ff89bd95f82c616785757264b37e042 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Fri, 10 Jul 2026 08:38:31 +0000 Subject: [PATCH 2/4] CI: retry only short probes so worst case fits the job budget Some json-images calls pass timeout=600; three attempts there could spend 30 minutes in one step and hit the job's timeout-minutes instead of failing with the Python error. Retry (3 attempts) only when timeout <= 300s, which covers the observed flaky 180-240s probes; longer probes keep the pre-PR single attempt. --- .github/workflows/studio-inference-smoke.yml | 18 ++++++++++++------ .../workflows/studio-mac-inference-smoke.yml | 18 ++++++++++++------ .../studio-windows-inference-smoke.yml | 18 ++++++++++++------ 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/.github/workflows/studio-inference-smoke.yml b/.github/workflows/studio-inference-smoke.yml index ce0c6f6ba4..ce4bf46425 100644 --- a/.github/workflows/studio-inference-smoke.yml +++ b/.github/workflows/studio-inference-smoke.yml @@ -467,15 +467,18 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. - for attempt in range(3): + # failures only; HTTP status errors surface immediately. Long + # probes (timeout > 300s) get a single attempt so the worst + # case stays inside the job's timeout-minutes budget. + attempts = 3 if timeout <= 300 else 1 + for attempt in range(attempts): try: with urllib.request.urlopen(req, timeout = timeout) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: - if attempt == 2: + if attempt == attempts - 1: raise print(f"[retry] {path}: {exc!r}", flush = True) time.sleep(15) @@ -972,15 +975,18 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. - for attempt in range(3): + # failures only; HTTP status errors surface immediately. Long + # probes (timeout > 300s) get a single attempt so the worst + # case stays inside the job's timeout-minutes budget. + attempts = 3 if timeout <= 300 else 1 + for attempt in range(attempts): try: with urllib.request.urlopen(req, timeout = timeout) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: - if attempt == 2: + if attempt == attempts - 1: raise print(f"[retry] {path}: {exc!r}", flush = True) time.sleep(15) diff --git a/.github/workflows/studio-mac-inference-smoke.yml b/.github/workflows/studio-mac-inference-smoke.yml index d9d98e3a16..805817b518 100644 --- a/.github/workflows/studio-mac-inference-smoke.yml +++ b/.github/workflows/studio-mac-inference-smoke.yml @@ -453,15 +453,18 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. - for attempt in range(3): + # failures only; HTTP status errors surface immediately. Long + # probes (timeout > 300s) get a single attempt so the worst + # case stays inside the job's timeout-minutes budget. + attempts = 3 if timeout <= 300 else 1 + for attempt in range(attempts): try: with urllib.request.urlopen(req, timeout = timeout) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: - if attempt == 2: + if attempt == attempts - 1: raise print(f"[retry] {path}: {exc!r}", flush = True) time.sleep(15) @@ -864,15 +867,18 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. - for attempt in range(3): + # failures only; HTTP status errors surface immediately. Long + # probes (timeout > 300s) get a single attempt so the worst + # case stays inside the job's timeout-minutes budget. + attempts = 3 if timeout <= 300 else 1 + for attempt in range(attempts): try: with urllib.request.urlopen(req, timeout = timeout) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: - if attempt == 2: + if attempt == attempts - 1: raise print(f"[retry] {path}: {exc!r}", flush = True) time.sleep(15) diff --git a/.github/workflows/studio-windows-inference-smoke.yml b/.github/workflows/studio-windows-inference-smoke.yml index 00cf9adcf1..740cde15fb 100644 --- a/.github/workflows/studio-windows-inference-smoke.yml +++ b/.github/workflows/studio-windows-inference-smoke.yml @@ -659,15 +659,18 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. - for attempt in range(3): + # failures only; HTTP status errors surface immediately. Long + # probes (timeout > 300s) get a single attempt so the worst + # case stays inside the job's timeout-minutes budget. + attempts = 3 if timeout <= 300 else 1 + for attempt in range(attempts): try: with urllib.request.urlopen(req, timeout = timeout) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: - if attempt == 2: + if attempt == attempts - 1: raise print(f"[retry] {path}: {exc!r}", flush = True) time.sleep(15) @@ -1098,15 +1101,18 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. - for attempt in range(3): + # failures only; HTTP status errors surface immediately. Long + # probes (timeout > 300s) get a single attempt so the worst + # case stays inside the job's timeout-minutes budget. + attempts = 3 if timeout <= 300 else 1 + for attempt in range(attempts): try: with urllib.request.urlopen(req, timeout = timeout) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise except (TimeoutError, ConnectionError, urllib.error.URLError) as exc: - if attempt == 2: + if attempt == attempts - 1: raise print(f"[retry] {path}: {exc!r}", flush = True) time.sleep(15) From e739dc1cca312e3041aac4dd60a7928f11e00026 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Fri, 10 Jul 2026 08:50:05 +0000 Subject: [PATCH 3/4] CI: give long smoke probes one capped retry Round two of bounding the retries: timeout>300s probes previously got a single attempt, so a transient stall in the 600s JSON-mode probes still failed on first occurrence. Give them one retry with the attempt timeout capped at 300s. Worst cases stay inside timeout-minutes: 240s probes 12.5 min, one 600s probe 15.25 min, the Windows JSON job's two long probes 30.5 min against its 35 minute budget. --- .github/workflows/studio-inference-smoke.yml | 24 +++++++++++-------- .../workflows/studio-mac-inference-smoke.yml | 24 +++++++++++-------- .../studio-windows-inference-smoke.yml | 24 +++++++++++-------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/.github/workflows/studio-inference-smoke.yml b/.github/workflows/studio-inference-smoke.yml index ce4bf46425..f540c11da4 100644 --- a/.github/workflows/studio-inference-smoke.yml +++ b/.github/workflows/studio-inference-smoke.yml @@ -467,13 +467,15 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Long - # probes (timeout > 300s) get a single attempt so the worst - # case stays inside the job's timeout-minutes budget. - attempts = 3 if timeout <= 300 else 1 + # failures only; HTTP status errors surface immediately. Bounded + # to fit the job's timeout-minutes: short probes get 3 full + # attempts, long probes one retry capped at 300s (a healthy + # server answers a retry quickly; a stalled one never does). + attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: - with urllib.request.urlopen(req, timeout = timeout) as resp: + t = timeout if attempt == 0 else min(timeout, 300) + with urllib.request.urlopen(req, timeout = t) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise @@ -975,13 +977,15 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Long - # probes (timeout > 300s) get a single attempt so the worst - # case stays inside the job's timeout-minutes budget. - attempts = 3 if timeout <= 300 else 1 + # failures only; HTTP status errors surface immediately. Bounded + # to fit the job's timeout-minutes: short probes get 3 full + # attempts, long probes one retry capped at 300s (a healthy + # server answers a retry quickly; a stalled one never does). + attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: - with urllib.request.urlopen(req, timeout = timeout) as resp: + t = timeout if attempt == 0 else min(timeout, 300) + with urllib.request.urlopen(req, timeout = t) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise diff --git a/.github/workflows/studio-mac-inference-smoke.yml b/.github/workflows/studio-mac-inference-smoke.yml index 805817b518..03c0a8580d 100644 --- a/.github/workflows/studio-mac-inference-smoke.yml +++ b/.github/workflows/studio-mac-inference-smoke.yml @@ -453,13 +453,15 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Long - # probes (timeout > 300s) get a single attempt so the worst - # case stays inside the job's timeout-minutes budget. - attempts = 3 if timeout <= 300 else 1 + # failures only; HTTP status errors surface immediately. Bounded + # to fit the job's timeout-minutes: short probes get 3 full + # attempts, long probes one retry capped at 300s (a healthy + # server answers a retry quickly; a stalled one never does). + attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: - with urllib.request.urlopen(req, timeout = timeout) as resp: + t = timeout if attempt == 0 else min(timeout, 300) + with urllib.request.urlopen(req, timeout = t) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise @@ -867,13 +869,15 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Long - # probes (timeout > 300s) get a single attempt so the worst - # case stays inside the job's timeout-minutes budget. - attempts = 3 if timeout <= 300 else 1 + # failures only; HTTP status errors surface immediately. Bounded + # to fit the job's timeout-minutes: short probes get 3 full + # attempts, long probes one retry capped at 300s (a healthy + # server answers a retry quickly; a stalled one never does). + attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: - with urllib.request.urlopen(req, timeout = timeout) as resp: + t = timeout if attempt == 0 else min(timeout, 300) + with urllib.request.urlopen(req, timeout = t) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise diff --git a/.github/workflows/studio-windows-inference-smoke.yml b/.github/workflows/studio-windows-inference-smoke.yml index 740cde15fb..0453c9212a 100644 --- a/.github/workflows/studio-windows-inference-smoke.yml +++ b/.github/workflows/studio-windows-inference-smoke.yml @@ -659,13 +659,15 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Long - # probes (timeout > 300s) get a single attempt so the worst - # case stays inside the job's timeout-minutes budget. - attempts = 3 if timeout <= 300 else 1 + # failures only; HTTP status errors surface immediately. Bounded + # to fit the job's timeout-minutes: short probes get 3 full + # attempts, long probes one retry capped at 300s (a healthy + # server answers a retry quickly; a stalled one never does). + attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: - with urllib.request.urlopen(req, timeout = timeout) as resp: + t = timeout if attempt == 0 else min(timeout, 300) + with urllib.request.urlopen(req, timeout = t) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise @@ -1101,13 +1103,15 @@ jobs: }, ) # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Long - # probes (timeout > 300s) get a single attempt so the worst - # case stays inside the job's timeout-minutes budget. - attempts = 3 if timeout <= 300 else 1 + # failures only; HTTP status errors surface immediately. Bounded + # to fit the job's timeout-minutes: short probes get 3 full + # attempts, long probes one retry capped at 300s (a healthy + # server answers a retry quickly; a stalled one never does). + attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: - with urllib.request.urlopen(req, timeout = timeout) as resp: + t = timeout if attempt == 0 else min(timeout, 300) + with urllib.request.urlopen(req, timeout = t) as resp: return resp.status, json.loads(resp.read().decode()) except urllib.error.HTTPError: raise From 33da775312204f2ba61f2cf8899e744fafb16276 Mon Sep 17 00:00:00 2001 From: danielhanchen Date: Fri, 10 Jul 2026 11:42:24 +0000 Subject: [PATCH 4/4] Tighten retry comments --- .github/workflows/studio-inference-smoke.yml | 14 ++++---------- .github/workflows/studio-mac-inference-smoke.yml | 14 ++++---------- .../workflows/studio-windows-inference-smoke.yml | 14 ++++---------- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/.github/workflows/studio-inference-smoke.yml b/.github/workflows/studio-inference-smoke.yml index f540c11da4..9f9bb26577 100644 --- a/.github/workflows/studio-inference-smoke.yml +++ b/.github/workflows/studio-inference-smoke.yml @@ -466,11 +466,8 @@ jobs: "Content-Type": "application/json", }, ) - # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Bounded - # to fit the job's timeout-minutes: short probes get 3 full - # attempts, long probes one retry capped at 300s (a healthy - # server answers a retry quickly; a stalled one never does). + # Retry transport failures only (HTTP errors raise immediately); + # short probes get 3 attempts, long probes 1 retry capped at 300s. attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: @@ -976,11 +973,8 @@ jobs: "Content-Type": "application/json", }, ) - # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Bounded - # to fit the job's timeout-minutes: short probes get 3 full - # attempts, long probes one retry capped at 300s (a healthy - # server answers a retry quickly; a stalled one never does). + # Retry transport failures only (HTTP errors raise immediately); + # short probes get 3 attempts, long probes 1 retry capped at 300s. attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: diff --git a/.github/workflows/studio-mac-inference-smoke.yml b/.github/workflows/studio-mac-inference-smoke.yml index 03c0a8580d..b7549ca8e7 100644 --- a/.github/workflows/studio-mac-inference-smoke.yml +++ b/.github/workflows/studio-mac-inference-smoke.yml @@ -452,11 +452,8 @@ jobs: "Content-Type": "application/json", }, ) - # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Bounded - # to fit the job's timeout-minutes: short probes get 3 full - # attempts, long probes one retry capped at 300s (a healthy - # server answers a retry quickly; a stalled one never does). + # Retry transport failures only (HTTP errors raise immediately); + # short probes get 3 attempts, long probes 1 retry capped at 300s. attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: @@ -868,11 +865,8 @@ jobs: "Content-Type": "application/json", }, ) - # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Bounded - # to fit the job's timeout-minutes: short probes get 3 full - # attempts, long probes one retry capped at 300s (a healthy - # server answers a retry quickly; a stalled one never does). + # Retry transport failures only (HTTP errors raise immediately); + # short probes get 3 attempts, long probes 1 retry capped at 300s. attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: diff --git a/.github/workflows/studio-windows-inference-smoke.yml b/.github/workflows/studio-windows-inference-smoke.yml index 0453c9212a..bf4f8e9ef1 100644 --- a/.github/workflows/studio-windows-inference-smoke.yml +++ b/.github/workflows/studio-windows-inference-smoke.yml @@ -658,11 +658,8 @@ jobs: "Content-Type": "application/json", }, ) - # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Bounded - # to fit the job's timeout-minutes: short probes get 3 full - # attempts, long probes one retry capped at 300s (a healthy - # server answers a retry quickly; a stalled one never does). + # Retry transport failures only (HTTP errors raise immediately); + # short probes get 3 attempts, long probes 1 retry capped at 300s. attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: @@ -1102,11 +1099,8 @@ jobs: "Content-Type": "application/json", }, ) - # Shared CI runners stall sporadically, so retry transport-level - # failures only; HTTP status errors surface immediately. Bounded - # to fit the job's timeout-minutes: short probes get 3 full - # attempts, long probes one retry capped at 300s (a healthy - # server answers a retry quickly; a stalled one never does). + # Retry transport failures only (HTTP errors raise immediately); + # short probes get 3 attempts, long probes 1 retry capped at 300s. attempts = 3 if timeout <= 300 else 2 for attempt in range(attempts): try: