Skip to content

OneTimeRuntime.open() awaits key generation past its own open deadline, wedging later opens #913

Description

@nedtwigg

Code: OneTimeRuntime.open in lib/src/remote/burrow/one-time-runtime.ts; its caller #openOneTime in lib/src/host/remote/service.ts, which stores the promise in #oneTimeOpening and returns it to every later open request while it is set.

Failure path: open() arms the ONE_TIME_OPEN_TIMEOUT_MS (8 s) deadline, then runs await generateNoiseKeyPair() before it returns the opened promise. If key generation stalls, the deadline still ends the runtime (unreachable) and the state settles, but open() itself does not return until key generation does. Until then the service's #oneTimeOpening stays set. Every later "One-time connection" click joins that stuck promise rather than opening a new runtime, and the panel cannot open a link until key generation completes or the host restarts. The phase guard after the await already stops a late socket, so the problem is only the hung promise.

Suggested fix: return opened without awaiting key generation inline. Run it as a detached step (void this.#mint()) that checks the phase after it settles, as the current guard does. To test it, inject a key generator that never resolves, advance the clock past ONE_TIME_OPEN_TIMEOUT_MS, and assert that open() resolves ended {reason: 'unreachable'} and that a second service open mints a new runtime.

Found while trimming #904, which had parked this as a spec "Known gap".

🤖 Generated with Claude Code

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