From 457750e20cc772a63cc5ded89378350bd53aa843 Mon Sep 17 00:00:00 2001 From: Patrick Buckley Date: Wed, 29 Jul 2026 02:45:10 -0700 Subject: [PATCH] fix(eval): close the parallel lane's per-item client The subprocess worker built a fresh client per work item and never closed it. Pool workers are reused across items, so each one accumulated a live transport per item for the life of the sweep. --- turnstone/eval/core.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/turnstone/eval/core.py b/turnstone/eval/core.py index 89fc16bf..2018839d 100644 --- a/turnstone/eval/core.py +++ b/turnstone/eval/core.py @@ -822,6 +822,21 @@ def _run_and_score_subprocess(params: dict[str, Any]) -> dict[str, Any]: case: dict[str, Any] = params["case"] run_tokens = 0 + try: + return _run_and_score_with(client, params, case, run_tokens) + finally: + # Pool workers are reused across work items, so an unclosed + # client accumulates one live transport per item inside the + # worker process for the life of the sweep. + with contextlib.suppress(Exception): + client.close() + + +def _run_and_score_with( + client: Any, params: dict[str, Any], case: dict[str, Any], run_tokens: int +) -> dict[str, Any]: + """The body of :func:`_run_and_score_subprocess`, client lifetime + owned by the caller.""" try: run_result = _run_single_test( client=client,