Conversation
|
CI classification: slice 5 has the same current-main baseline failure seen on other PRs at base |
1fc104c to
160279b
Compare
|
Replacement CI is feature-clean; the sole Python failure is the unrelated wall-clock assertion in Fresh-process verification:
I attempted to rerun failed jobs through |
160279b to
347ba9d
Compare
|
Current-main refresh complete at
The old timing-only failure is gone on the fresh run; this PR is mergeable and ready for review. |
|
The sync
Reproduced on On the test in I opened #87168 with the async-side fix: make Suggestion: keep the sync |
fix(web): serialize provider client initialization The double-checked locking is correct: the unlocked fast path reads the cache slot, and the slow path re-checks under the lock before constructing and publishing, so concurrent first-use builds exactly one client. A few observations:
|
347ba9d to
a442a77
Compare
|
@goslingmanagment Updated in The PR description now scopes this to the sync portions of #24736 and points the loop-affine async lifecycle to #87168. Verification on current main |
What does this PR do?
Prevents concurrent first-use calls from constructing and leaking duplicate synchronous Parallel and Exa SDK clients.
Addresses the sync Parallel and Exa portions of #24736. The loop-affine
AsyncParallellifecycle is intentionally excluded and handled by #87168.Root cause
The two synchronous lazy getters read their canonical cache slots on
tools.web_tools, constructed a client without synchronization, and then published it. A barrier reproduction on current main made simultaneous callers construct duplicate clients on both paths.The provider migration moved these getters out of
tools/web_tools.py, so synchronization belongs in the canonical modules underplugins/web/parallelandplugins/web/exa.Changes
Async ownership
This PR does not change
_get_async_client()relative to current main and no longer asserts thatAsyncParallelshould be a process-wide singleton.AsyncParallelowns an HTTPX transport with event-loop affinity, so #87168 gives each extraction its own client and closes it on the loop that used it.Validation
ruff checkon all changed Python filesruff format --checkon the new testuv lock --checkgit diff --checkOverlap and attribution
This is the current-main refresh invited by closed PR #24741 from @wesleysimplicio. That PR identified the original races before the provider migration. The current implementation preserves the valid sync-client direction at the canonical provider owners. Thanks to @goslingmanagment for identifying the distinct async loop-ownership invariant and implementing it in #87168.