Skip to content

fix(sandbox): single-flight cached dependency factories#3935

Draft
cosin2077 wants to merge 1 commit into
openai:mainfrom
cosin2077:fix/dependency-single-flight
Draft

fix(sandbox): single-flight cached dependency factories#3935
cosin2077 wants to merge 1 commit into
openai:mainfrom
cosin2077:fix/dependency-single-flight

Conversation

@cosin2077

Copy link
Copy Markdown

Summary

This pull request fixes cached sandbox dependency factories so concurrent requests for the same key share one in-flight initialization.

Previously, the cache was populated only after a factory completed, so overlapping require() calls could execute the same async factory multiple times and register multiple owned resources. The implementation now tracks one pending task per cached key, shields shared initialization from individual waiter cancellation, clears failed tasks for retry, and prevents stale or post-close results from entering the cache. Container shutdown is also single-flight and waits for tracked cleanup tasks so cancellation, rebind, and close interleavings cannot leak owned results.

Uncached factories continue to execute once per request.

Test plan

  • uv run pytest -q tests/sandbox/test_dependencies.py (18 passed)
  • Related snapshot/runtime cleanup tests (13 passed)
  • bash .agents/skills/code-change-verification/scripts/run.sh (format, lint, typecheck, and full test suite passed)
  • Reviewed the final diff against origin/main; Standards and Spec reviews reported no remaining findings.

Issue number

No linked issue. A pre-submission search found no open issue or pull request covering this fix.

Checks

  • I've added new tests, if relevant
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass
  • If using Codex, I've run /review before submitting this PR

@seratch seratch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One ownership issue blocks merge. A stale or post-close factory result is currently closed immediately via _discard_factory_result(). The same object may already be owned by another binding or returned by the replacement binding; the existing identity deduplication in aclose() shows that aliased owned results are supported. Eagerly closing that object can therefore invalidate surviving work or cause it to be closed twice.
Please route stale and post-close owned results through the container's identity-deduplicated owned-result cleanup instead of closing them eagerly. Please also add controlled rebind and close tests where the stale and surviving/current factories return the same closable object, asserting that the survivor remains usable until shutdown and that the object is closed exactly once. After that focused change, this should be in good shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants