Gateway
Блокування Gateway
Навіщо
- Лише один процес gateway має володіти каталогом стану; запускайте додаткові gateway з ізольованими профілями, каталогами стану, конфігураціями та портами.
- Забезпечення стійкості до аварійних завершень/SIGKILL без залишення застарілих файлів блокування.
- Швидке завершення з чіткою помилкою, коли портом уже володіє інший gateway.
Три рівні
Під час запуску володіння забезпечується у три послідовні кроки:
- Блокування володіння станом отримує блокування, ключем якого є канонічний каталог стану. У ньому бере участь кожен Gateway, зокрема Gateway, запущені з
OPENCLAW_ALLOW_MULTI_GATEWAY=1, щоб деструктивне обслуговування SQLite не виконувалося одночасно з активним власником. - Блокування конфігурації отримує історичне блокування для кожної конфігурації та записує порт середовища виконання. Режим кількох Gateway пропускає цю перевірку єдиного екземпляра конфігурації, але зберігає блокування володіння станом.
- Прив’язування сокета прив’язує обробник HTTP/WebSocket (типово
ws://127.0.0.1:18789) як ексклюзивний TCP-обробник.
Кожен рівень може завершитися помилкою незалежно та створює власну GatewayLockError.
Блокування стану та конфігурації
-
Активність блокування визначається за записаним PID, ідентифікатором початку процесу на платформі, якщо він доступний, та ідентифікатором процесу Gateway. Перевірений власник залишається повноважним під час запуску ще до того, як його порт почне прослуховуватися.
-
Спеціалізований координатор SQLite послідовно виконує перевірку метаданих, повернення володіння від застарілого власника та заміну блокування. Його ексклюзивна транзакція автоматично завершується, якщо процес-власник аварійно завершує роботу.
-
Якщо файл блокування відсутній або записаний процес-власник уже не працює, під час запуску блокування повертається та виконання триває.
-
Якщо будь-яке з блокувань активно утримується, запуск повторює спроби протягом щонайбільше 5 секунд (типово), перш ніж припинити їх:
text GatewayLockError("gateway уже запущено (pid <pid>); час очікування блокування вичерпано через <ms>мс")
Прив’язування сокета
-
У разі
EADDRINUSEзапуск повторює спробу прив’язування до 20 разів з інтервалом 500мс (загалом приблизно 10 секунд), щоб перечекати періодTIME_WAITпісля нещодавнього завершення процесу. -
Якщо після повторних спроб порт усе ще використовується:
text GatewayLockError("інший екземпляр gateway уже прослуховує ws://127.0.0.1:<port>") -
Інші помилки прив’язування:
text GatewayLockError("не вдалося прив’язати сокет gateway до ws://127.0.0.1:<port>: <cause>")
Під час завершення роботи gateway закриває сервер HTTP/WebSocket і видаляє свої файли блокування стану та конфігурації.
Примітки щодо експлуатації
- Якщо порт зайнятий іншим процесом, що не є gateway, помилка буде такою самою; звільніть порт або виберіть інший за допомогою
openclaw gateway --port <port>. OPENCLAW_ALLOW_MULTI_GATEWAY=1дозволяє використовувати кілька екземплярів конфігурації/середовища виконання, але не спільний змінюваний стан. Кожному екземпляру все одно потрібен унікальнийOPENCLAW_STATE_DIR.- Під керуванням диспетчера служб новий процес gateway, який стикається з будь-якою з наведених вище помилок, спочатку перевіряє
/healthzна наявному процесі. Якщо цей процес справний, новий процес залишає керування за ним замість завершення з помилкою. У systemd він завершується з кодом78; параметр модуляRestartPreventExitStatus=78запобігає зацикленнюRestart=alwaysчерез конфлікт блокування абоEADDRINUSE. Якщо наявний процес так і не стає справним, повторні перевірки справності обмежуються в часі, після чого запуск завершується з наведеною вище помилкою блокування замість нескінченного циклу. - Застосунок macOS використовує власний спрощений захист за PID перед запуском gateway; фактичне забезпечення під час виконання здійснюють описані вище блокування файлу та прив’язування сокета.
Пов’язані матеріали
- Кілька Gateway - запуск кількох екземплярів з унікальними портами
- Усунення несправностей - діагностика
EADDRINUSEі конфліктів портів