Skip to content

fix(sandbox): serialize E2B acquire and release per thread #4333

Description

@luojiyin1987

Problem

E2BSandboxProvider.acquire() holds a per-(user_id, thread_id) lock. release() does not use that lock.

Release removes the active mappings before it syncs outputs, refreshes the remote timeout, closes the local client, and adds the sandbox to the warm pool. A concurrent acquire for the same thread can observe neither an active nor a warm sandbox.

It can then reconnect to the same remote VM through discovery, or create a new VM while release still operates on the old client.

Expected behavior

For one Gateway process, acquire must wait until release finishes the thread state transition. It must then reclaim the warm sandbox or create a replacement after release completes.

Proposed direction

  • Use the existing per-thread lock for the full release transition.
  • Do not hold the provider-wide lock across remote IO.
  • Add an explicit releasing state or clear state-transition logs.
  • Add a concurrency regression test that blocks output sync and asserts acquire does not discover or create early.

Scope

This fixes the in-process race. Multi-process Gateway deployments still need a distributed lease or an E2B-side atomic claim.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal priorityarea:sandboxSandboxed execution and docker/bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions