目的
- 同一ホスト上の同じベースポートにおいて、ゲートウェイのインスタンスが 1 つだけ実行されることを保証します。追加のゲートウェイを起動するには、分離されたプロファイルと一意のポート番号を使用する必要があります。
- プロセスのクラッシュや
SIGKILLが発生しても、古いロックファイルが残ることなく、正常に復旧できるようにします。 - 制御用ポートが既に占有されている場合、明確なエラーを表示して即座に終了(Fail-fast)させます。
仕組み
- ゲートウェイは起動時に、排他的な TCP リスナーを使用して WebSocket 用ポート(デフォルト
ws://127.0.0.1:18789)を即座にバインドします。 - バインド時に
EADDRINUSEエラーが発生した場合、GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>")を投げて起動を中断します。 - OS は、クラッシュや
SIGKILLを含め、プロセスが終了すれば自動的にリスナーを解放します。そのため、個別のロックファイル管理やクリーンアップ処理は不要です。 - 正常終了時には、ゲートウェイは WebSocket サーバーおよび背後の HTTP サーバーを閉じ、速やかにポートを開放します。
エラーの種類
- 他のプロセスが既にポートを使用している場合、起動時に
GatewayLockError("another gateway instance is already listening on ws://127.0.0.1:<port>")が発生します。 - その他のバインド失敗(権限不足など)は、
GatewayLockError("failed to bind gateway socket on ws://127.0.0.1:<port>: …")として報告されます。
運用上の注意
- ポートが「OpenClaw 以外の」プロセスによって占有されている場合も、同じエラーが発生します。ポートを解放するか、
openclaw gateway --port <port>で別のポート番号を指定してください。 - macOS アプリは、ゲートウェイプロセスを起動する前に独自の軽量な PID ガードを維持していますが、最終的なランタイムロックは WebSocket のバインドによって強制されます。