Gateway Lock

Gateway lock

Last updated: 2025-12-11

Why

  • Ensure only one gateway instance runs per base port on the same host; additional gateways must use isolated profiles and unique ports.
  • Survive crashes/SIGKILL without leaving stale lock files.
  • Fail fast with a clear error when the control port is already occupied.

Why

  • 确保每个 base port 在 same host 上只有一个 gateway instance 运行;additional gateways 必须使用 isolated profiles 和 unique ports。
  • Survive crashes/SIGKILL without leaving stale lock files。
  • Fail fast with a clear error when the control port is already occupied。

Mechanism

  • The gateway binds the WebSocket listener(default ws://127.0.0.1:18789)immediately on startup using an exclusive TCP listener。
  • 如果 bind fails with EADDRINUSE,startup throws GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>")
  • The OS releases the listener automatically on any process exit,including crashes and SIGKILL—no separate lock file or cleanup step is needed。
  • On shutdown the gateway closes the WebSocket server and underlying HTTP server to free the port promptly。

Error surface

  • 如果 another process holds the port,startup throws GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>")
  • Other bind failures surface as GatewayLockError("failed to bind gateway socket on ws://127.0.0.1:<port>: …")

Operational notes

  • 如果 the port is occupied by another process,the error is the same; free the port or choose another with openclaw gateway --port <port>
  • The macOS app still maintains its own lightweight PID guard before spawning the gateway; the runtime lock is enforced by the WebSocket bind。