Skip to content

Commit afdb80f

Browse files
authored
Merge pull request #213 from zlxlabs/card/VideoTranscriptAPI-261009-probe
容量探针就绪等待由 sleep 改为轮询(解开 #210 quality 红)
2 parents be2e4fd + 2a095f8 commit afdb80f

1 file changed

Lines changed: 67 additions & 14 deletions

File tree

‎scripts/perf/local_upload_capacity.py‎

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,63 @@ def _wait_for_terminal(db_path: Path, task_ids: list[str], process: subprocess.P
235235
raise ExperimentFailure("sandbox_tasks_did_not_reach_terminal_state")
236236

237237

238+
def _sandbox_log_tail(*paths: Path, max_bytes: int = 4096) -> str:
239+
chunks: list[str] = []
240+
for path in paths:
241+
if not path.is_file():
242+
continue
243+
data = path.read_bytes()
244+
if not data:
245+
continue
246+
chunks.append(data[-max_bytes:].decode("utf-8", errors="replace"))
247+
return "\n".join(chunks)
248+
249+
250+
def _wait_for_sandbox_api(
251+
process: subprocess.Popen,
252+
*,
253+
base_url: str,
254+
token: str,
255+
log_paths: tuple[Path, ...],
256+
timeout_seconds: float = 30.0,
257+
interval_seconds: float = 0.2,
258+
) -> None:
259+
parsed = urlparse(base_url)
260+
deadline = time.monotonic() + timeout_seconds
261+
last_error = "no_probe_attempt"
262+
while time.monotonic() < deadline:
263+
if process.poll() is not None:
264+
tail = _sandbox_log_tail(*log_paths)
265+
raise ExperimentFailure(
266+
f"sandbox_api_failed_to_start returncode={process.returncode} log_tail={tail!r}"
267+
)
268+
try:
269+
connection = http.client.HTTPConnection(parsed.hostname, parsed.port, timeout=1)
270+
try:
271+
connection.request(
272+
"GET",
273+
"/api/uploads/capabilities",
274+
headers={"Authorization": f"Bearer {token}"},
275+
)
276+
readiness = connection.getresponse()
277+
body = readiness.read()
278+
finally:
279+
connection.close()
280+
if readiness.status == 200 and json.loads(body).get("enabled") is True:
281+
return
282+
last_error = f"http_{readiness.status}"
283+
except (OSError, http.client.HTTPException, json.JSONDecodeError) as exc:
284+
last_error = f"{type(exc).__name__}:{exc}"
285+
remaining = deadline - time.monotonic()
286+
if remaining <= 0:
287+
break
288+
time.sleep(min(interval_seconds, remaining))
289+
tail = _sandbox_log_tail(*log_paths)
290+
raise ExperimentFailure(
291+
f"sandbox_api_not_ready timeout_seconds={timeout_seconds} last_error={last_error} log_tail={tail!r}"
292+
)
293+
294+
238295
def run_experiment(duration_seconds: int) -> int:
239296
if duration_seconds < 1 or duration_seconds > 30:
240297
raise ExperimentFailure("duration_seconds_must_be_between_1_and_30")
@@ -305,23 +362,19 @@ def __init__(self, *args, **kwargs):
305362
stderr=subprocess.STDOUT,
306363
)
307364
cleanup.callback(_stop_process, process)
308-
time.sleep(2)
309-
if process.poll() is not None:
310-
raise ExperimentFailure("sandbox_api_failed_to_start")
311365

312366
base_url = f"http://127.0.0.1:{api_port}"
313-
parsed = urlparse(base_url)
314-
connection = http.client.HTTPConnection(parsed.hostname, parsed.port, timeout=5)
315-
connection.request(
316-
"GET",
317-
"/api/uploads/capabilities",
318-
headers={"Authorization": "Bearer sandbox-token-never-use-outside-this-run"},
367+
_wait_for_sandbox_api(
368+
process,
369+
base_url=base_url,
370+
token="sandbox-token-never-use-outside-this-run",
371+
log_paths=(
372+
service_log_path,
373+
root / "data" / "logs" / "sandbox-api.log",
374+
),
375+
timeout_seconds=30.0,
376+
interval_seconds=0.2,
319377
)
320-
readiness = connection.getresponse()
321-
capabilities = json.loads(readiness.read())
322-
connection.close()
323-
if readiness.status != 200 or capabilities.get("enabled") is not True:
324-
raise ExperimentFailure("sandbox_upload_receiver_not_ready")
325378

326379
starts = threading.Barrier(3)
327380
data_temp = root / "data" / "temp"

0 commit comments

Comments
 (0)