Gateway

Блокування Gateway

Навіщо

  • Лише один процес gateway має володіти каталогом стану; запускайте додаткові gateway з ізольованими профілями, каталогами стану, конфігураціями та портами.
  • Забезпечення стійкості до аварійних завершень/SIGKILL без залишення застарілих файлів блокування.
  • Швидке завершення з чіткою помилкою, коли портом уже володіє інший gateway.

Три рівні

Під час запуску володіння забезпечується у три послідовні кроки:

  1. Блокування володіння станом отримує блокування, ключем якого є канонічний каталог стану. У ньому бере участь кожен Gateway, зокрема Gateway, запущені з OPENCLAW_ALLOW_MULTI_GATEWAY=1, щоб деструктивне обслуговування SQLite не виконувалося одночасно з активним власником.
  2. Блокування конфігурації отримує історичне блокування для кожної конфігурації та записує порт середовища виконання. Режим кількох Gateway пропускає цю перевірку єдиного екземпляра конфігурації, але зберігає блокування володіння станом.
  3. Прив’язування сокета прив’язує обробник 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; фактичне забезпечення під час виконання здійснюють описані вище блокування файлу та прив’язування сокета.

Пов’язані матеріали

Was this useful?
On this page

On this page