Skip to content

fix(core): a docker session that destroys races the one that replaces it #23

Description

@amondnet

session(sandboxId).destroy() in packages/core/src/sandbox/docker/provider.ts evicts its cached ContainerHandle in a finally after the teardown:

destroy: async () => {
  try {
    await created.destroy()
  }
  finally {
    if (handles.get(sandboxId) === handle) {
      handles.delete(sandboxId)
    }
  }
},

Two races follow from the ordering, and they are the pair the microsandbox backend hit in #12.

Evicting late. While created.destroy() is in flight the handle is still registered, so a concurrent session(id) adopts it, reacquires, and starts using a container this call is removing. The identity check then still passes, so the destroy evicts the replacement's handle on its way out.

Evicting early is not the fix on its own. A sandbox id resolves to a container name, and createContainerHandle's acquire adopts whatever the daemon already has under that name — which is what makes an id resumable across host processes. So a fresh handle built during the teardown attaches to the container being removed.

#12 settled this for microsandbox/provider.ts by doing both: evict before awaiting, and publish the teardown per sandbox id so a handle built while one is in flight holds ready/peek/remove behind it. local/root.ts states the same rule for a directory rather than a container. The Docker provider is pre-existing on main and outside #12's diff, which is why it was left alone there.

just-bash needs no equivalent: a new just-bash handle is an independent virtual filesystem rather than a second claim on the same named machine.

Related: #21, also a construction the three new backends corrected and the Docker original still carries.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions