UniSet 2.44.3
Содержание директории Launcher
Директория графа зависимостей Launcher:
Launcher

Директории

 
tests

Файлы

 
ConfigLoader.h
 
DependencyResolver.h
 
HealthChecker.h
 
HTTPHandler.h
 
LauncherHttpRegistry.h
 
OmniNamesManager.h
 
ProcessInfo.h
 
ProcessManager.h
 
ProcessTemplate.h

Подробное описание

Менеджер жизненного цикла процессов для распределённых систем UniSet2. Управляет последовательностью запуска, мониторингом состояния и автоматическим перезапуском.

Возможности

  • Упорядоченный запуск: Запуск процессов в порядке зависимостей (naming → SM → обмены)
  • Мониторинг состояния: Отслеживание работоспособности процессов и автоматический перезапуск при сбое
  • Проверка готовности: Ожидание готовности процессов (TCP порт, CORBA объект, HTTP endpoint)
  • REST API: HTTP API для мониторинга статуса и управления процессами
  • Конфигурация: XML-конфигурация, интегрированная с configure.xml UniSet2
  • Фильтрация по узлам: Запуск определённых процессов на определённых узлах
  • Флаг пропуска: Временное отключение процессов без удаления из конфига (skip="1")

Использование

uniset2-launcher --confile configure.xml [--localNode Node1] [ОПЦИИ] [-- ARGS...]

Проброс аргументов

Неизвестные launcher'у аргументы автоматически пробрасываются в дочерние процессы:

# --uniset-port и --lockDir будут переданы всем дочерним процессам
uniset2-launcher --confile config.xml --uniset-port 2809 --lockDir /tmp

Также можно явно указать аргументы для проброса через --:

uniset2-launcher --confile config.xml -- --custom-arg value

Опции

Опция Описание
--confile FILE Конфигурационный файл (обязательно)
--localNode NAME Имя локального узла (по умолчанию: из атрибута localNode в конфиге)
--launcher-name NAME Имя секции Launcher в конфиге
--http-port PORT Порт HTTP API (0 = отключено)
--http-host HOST Хост HTTP API (по умолчанию: 0.0.0.0)
--http-whitelist IPs Whitelist IP/подсетей через запятую
--http-blacklist IPs Blacklist IP/подсетей через запятую
--read-token TOKEN Bearer-токен для доступа к чтению (UI, GET API)
--control-token TOKEN Bearer-токен для управления (POST restart/stop/start)
--html-template FILE Пользовательский HTML-шаблон
--health-interval MS Интервал проверки состояния в мс (по умолчанию: 5000)
--stop-timeout MS Таймаут graceful shutdown в мс (по умолчанию: 5000)
--uniset-port PORT UniSet/CORBA порт (default: auto=UID+52809)
--omni-logdir DIR Каталог логов omniNames (по умолчанию: $TMPDIR/omniORB)
--default-ready-check TYPE Проверка готовности по умолчанию (none, tcp:PORT, и т.д.)
--disable-admin-create Не вызывать uniset2-admin –create после запуска omniNames
--no-monitor Не мониторить процессы после запуска
--runlist, --dry-run Показать что будет запущено без реального запуска
--verbose Подробный вывод

Конфигурация

Добавьте секцию <Launcher> в ваш configure.xml.

Упрощённая конфигурация (рекомендуется)

С использованием шаблонов процессов можно использовать минимальную конфигурацию:

<Launcher name="Launcher1"
commonArgs="--confile ${CONFFILE} --localNode ${NODE_NAME}">
<ProcessGroups>
<group name="sharedmemory" order="1">
<process name="SharedMemory"/>
</group>
<group name="exchanges" order="2" depends="sharedmemory">
<process name="UNetExchange1"/>
<process name="MBTCPMaster1"/>
</group>
</ProcessGroups>
</Launcher>

Launcher автоматически:

  • Определяет тип процесса по префиксу имени (SharedMemory*, UNet*, MBTCPMaster* и т.д.)
  • Устанавливает правильную команду (uniset2-smemory, uniset2-unetexchange и т.д.)
  • Устанавливает аргументы по умолчанию (--smemory-id, --unet-name и т.д.)
  • Настраивает проверку готовности через CORBA (corba:ProcessName)
  • Добавляет --smemory-id для процессов, которым нужен SharedMemory

Использование атрибута type

Для нестандартных имён укажите тип явно:

<process name="ModbusTCP1" type="MBTCPMaster"/>
<process name="SM_Main" type="SharedMemory"/>

Частичное переопределение

Переопределение отдельных атрибутов с сохранением значений из шаблона:

<process name="SharedMemory" readyTimeout="60000" critical="true"/>
<process name="UNetExchange1" nodeFilter="Node1,Node2"/>

Полная конфигурация (Legacy)

Для полного контроля или пользовательских процессов:

<Launcher name="Launcher1"
healthCheckInterval="5000"
restartDelay="1000"
maxRestartDelay="30000"
httpPort="8080"
commonArgs="--confile ${CONFFILE} --localNode ${NODE_NAME}">
<ProcessGroups>
<!-- Группа 0: Naming Service (запускается первой) -->
<group name="naming" order="0">
<process name="omniNames"
command="omniNames"
args="-start -logdir /var/log/omninames"
readyCheck="tcp:2809"
readyTimeout="30000"/>
</group>
<!-- Группа 1: SharedMemory (после naming) -->
<group name="sharedmemory" order="1" depends="naming">
<process name="SharedMemory"
command="uniset2-smemory"
readyCheck="corba:SharedMemory"
readyTimeout="10000"/>
</group>
<!-- Группа 2: Обмены (после SM) -->
<group name="exchanges" order="2" depends="sharedmemory">
<process name="UNetExchange"
command="uniset2-unetexchange"
nodeFilter="Node1,Node2"/>
<!-- Процесс без перезапуска -->
<process name="ModbusMaster"
command="uniset2-mbtcpmaster"
maxRestarts="-1"/>
<!-- Временно отключённый процесс -->
<process name="MQTTPublisher"
command="uniset2-mqttpublisher"
skip="1"/>
</group>
</ProcessGroups>
<Environment>
<var name="CONFFILE" value="/app/configure.xml"/>
</Environment>
</Launcher>

Атрибуты Launcher

Атрибут Описание По умолчанию
name Имя секции Launcher -
healthCheckInterval Интервал проверки состояния (мс) 5000
restartDelay Начальная задержка перед перезапуском (мс) 1000
maxRestartDelay Максимальная задержка (экспоненциальный backoff) (мс) 30000
restartWindow Временное окно для подсчёта перезапусков (мс) 60000
maxRestarts Максимальное количество перезапусков (0 = бесконечно) 0
httpPort Порт HTTP API (0 = отключено) 0
commonArgs Общие аргументы, добавляемые ко всем процессам ""
defaultReadyCheck Проверка готовности по умолчанию для процессов без явной none

Общие аргументы

Используйте commonArgs чтобы не повторять общие аргументы как --confile и --localNode:

<Launcher name="Launcher1"
commonArgs="--confile ${CONFFILE} --localNode ${NODE_NAME}">
<ProcessGroups>
<group name="sm" order="0">
<!-- Не нужно повторять --confile и --localNode -->
<process name="SharedMemory" command="uniset2-smemory"/>
<!-- Специфичные аргументы процесса добавляются после commonArgs -->
<process name="UNetExchange" command="uniset2-unetexchange"
args="--unet-name UNet1"/>
</group>
</ProcessGroups>
</Launcher>

Результирующая командная строка для UNetExchange:

uniset2-unetexchange --confile ${CONFFILE} --localNode ${NODE_NAME} --unet-name UNet1

Атрибуты процесса

Атрибут Описание По умолчанию
name Имя процесса (обязательно) -
type Тип процесса для поиска шаблона авто-определение
command Путь к исполняемому файлу из шаблона
args Аргументы командной строки из шаблона
rawArgs Отдельные аргументы без commonArgs ""
workDir Рабочий каталог текущий
readyCheck Проверка готовности (см. ниже) из шаблона
readyTimeout Таймаут проверки готовности (мс) 10000
checkPause Пауза между проверками готовности (мс) 500
healthCheck Проверка работоспособности (watchdog) нет
healthFailThreshold Количество неудачных liveness проверок до рестарта 3
ignoreFail Игнорировать сбой процесса (не останавливать launcher после исчерпания попыток) false
maxRestarts Попытки перезапуска: -1 = не рестартовать, 0 = бесконечно, >0 = ограничено 0
restartDelay Начальная задержка перед перезапуском (мс) 1000
maxRestartDelay Максимальная задержка (экспоненциальный backoff) (мс) 30000
nodeFilter Запуск на определённых узлах все
skip Пропустить этот процесс (не запускать) false
manual Запуск только вручную через REST API false
oneshot Процесс запускается один раз и завершается false
oneshotTimeout Таймаут для oneshot процесса (мс) 30000
afterRun Shell-команда для запуска после старта процесса ""

Фильтрация по узлам (nodeFilter)

Атрибут nodeFilter позволяет указать, на каких узлах должен запускаться процесс:

<!-- Запуск только на Node1 и Node2 -->
<process name="UNetExchange1" nodeFilter="Node1,Node2"/>
<!-- Запуск только на Node3 -->
<process name="MBTCPMaster1" nodeFilter="Node3"/>
<!-- Запуск на всех узлах (по умолчанию) -->
<process name="SharedMemory"/>

Правила:

  • Пустой nodeFilter = запуск на ВСЕХ узлах
  • Список узлов = запуск только на указанных узлах
  • Имена чувствительны к регистру (Node1node1)
  • Текущий узел определяется параметром --localNode

При запуске uniset2-launcher --localNode Node1:

  • nodeFilter="Node1,Node2" → процесс запустится
  • nodeFilter="Node3" → процесс не запустится
  • nodeFilter="" (пусто) → процесс запустится

В режиме --runlist пропущенные по фильтру процессы отображаются в секции "Skipped".

Пропуск процессов (skip)

Используйте skip="1" для временного отключения процесса без удаления из конфигурации:

<process name="ModbusMaster" command="uniset2-mbtcpmaster" skip="1"/>

Пропущенные процессы:

  • Не запускаются launcher'ом
  • Не влияют на статус allRunning (проверка состояния проходит успешно)
  • Отображаются в REST API с "skip": true и "state": "stopped"
  • Могут быть включены удалением атрибута skip и перезапуском launcher'а

Это полезно для:

  • Отладки (временное отключение некоторых процессов)
  • Поэтапного развёртывания
  • Конфигураций для конкретных узлов без дублирования файлов конфигурации

Ручной запуск процессов (manual)

Используйте manual="1" для процессов, которые не должны запускаться автоматически, но могут быть запущены через REST API или Web UI:

<process name="DiagTool" command="uniset2-diag" manual="1"/>
<process name="DebugLogger" command="uniset2-logdb" manual="1" ignoreFail="true"/>

Процессы с manual="1":

  • Не запускаются автоматически при старте launcher'а
  • Не влияют на статус allRunning пока не были запущены
  • Могут быть запущены через REST API: POST /api/v2/launcher/process/{name}/start
  • После запуска ведут себя как обычные процессы (перезапуск, мониторинг)
  • Отображаются в REST API с "manual": true
  • В режиме --runlist отмечаются как (manual)

Отличие от skip:

  • skip="1" — процесс полностью игнорируется, нельзя запустить через API
  • manual="1" — процесс не запускается автоматически, но можно запустить через API

Это полезно для:

  • Диагностических утилит (запускаются по необходимости)
  • Процессов для обслуживания системы
  • Дополнительных сервисов, которые не нужны постоянно

Типы проверки готовности

Тип Формат Пример
TCP tcp:host:port или tcp:port tcp:2809, tcp:localhost:4840
CORBA corba:ObjectName corba:SharedMemory
HTTP http:url http://localhost:8080/health
File file:path file:/var/run/service.pid

Для отключения проверки готовности используйте readyCheck="none".

Проверка готовности по умолчанию

По умолчанию процессы без явного readyCheck и без шаблона не имеют проверки готовности. Можно задать проверку готовности по умолчанию на уровне Launcher:

В конфигурации:

<Launcher name="Launcher1" defaultReadyCheck="tcp:localhost:8080">
<ProcessGroups>
<group name="services" order="1">
<!-- Эти процессы используют defaultReadyCheck -->
<process name="CustomService1" command="./service1"/>
<process name="CustomService2" command="./service2"/>
<!-- Этот процесс переопределяет проверку -->
<process name="CustomService3" command="./service3" readyCheck="http://localhost:9000/health"/>
</group>
</ProcessGroups>
</Launcher>

Через командную строку:

uniset2-launcher --confile config.xml --default-ready-check "tcp:localhost:8080"

Приоритет (от высшего к низшему):

  1. Явный readyCheck атрибут процесса
  2. readyCheck из шаблона процесса (для известных типов)
  3. defaultReadyCheck из конфигурации Launcher
  4. Нет проверки (процесс считается готовым сразу)

Health Check Watchdog

В отличие от readyCheck (проверяется при старте), healthCheck проверяет работоспособность процесса во время работы. Если процесс перестал отвечать (зависание, deadlock), watchdog автоматически перезапустит его.

<!-- Проверять TCP порт каждые healthCheckInterval мс -->
<process name="MyService"
command="./my-service"
healthCheck="tcp:8080"
healthFailThreshold="3"/>
<!-- Проверять HTTP endpoint -->
<process name="WebService"
command="./web-service"
healthCheck="http://localhost:9000/health"
healthFailThreshold="5"/>

Логика работы:

  • Каждые healthCheckInterval мс (по умолчанию 5000) проверяется healthCheck
  • При неудачной проверке увеличивается счётчик неудач
  • При успешной проверке счётчик сбрасывается
  • Когда счётчик достигает healthFailThreshold — процесс перезапускается (SIGTERM → пауза → SIGKILL)

Атрибуты:

  • healthCheck — проверка (формат такой же как readyCheck: tcp:port, http://url, corba:Name, file:path)
  • healthFailThreshold — количество последовательных неудач до рестарта (по умолчанию 3, 0 = отключить)

Отличие от обычного мониторинга:

  • Обычный мониторинг проверяет только существование процесса (PID)
  • healthCheck проверяет отклик процесса (сеть, файл и т.д.)

Это полезно для обнаружения:

  • Зависаний процесса (deadlock)
  • Утечек ресурсов, приводящих к неответу
  • Сетевых проблем в распределённых системах

Автоматический перезапуск

По умолчанию все процессы автоматически перезапускаются при падении с экспоненциальным backoff:

delay = min(restartDelay * 2^(attempt-1), maxRestartDelay)

Логика перезапуска:

  • maxRestarts=0 (по умолчанию) — бесконечные перезапуски
  • maxRestarts=-1 — отключить перезапуск
  • maxRestarts=N (N>0) — ограничить количество попыток
  • ignoreFail="true" — после исчерпания попыток не останавливать launcher (процесс остаётся в Failed)

Пример последовательности перезапусков (restartDelay=1000, maxRestartDelay=30000):

  • Попытка 1: 1 сек
  • Попытка 2: 2 сек
  • Попытка 3: 4 сек
  • Попытка 4: 8 сек
  • Попытка 5: 16 сек
  • Попытка 6+: 30 сек (достигнут максимум)

Конфигурация на уровне Launcher:

<Launcher name="Launcher1"
restartDelay="1000"
maxRestartDelay="30000"
maxRestarts="0">
<!-- maxRestarts="0" — бесконечные перезапуски (по умолчанию) -->
</Launcher>

На уровне процесса:

<!-- Ограничить до 10 попыток -->
<process name="UNetExchange" maxRestarts="10"/>
<!-- Отключить перезапуск -->
<process name="OptionalService" maxRestarts="-1"/>
<!-- или -->
<process name="OptionalService" ignoreFail="true"/>

При исчерпании попыток:

  • Если процесс критический (по умолчанию) — launcher останавливается
  • Если ignoreFail="true" — процесс остаётся в состоянии Failed

Состояния процесса:

  • running — процесс работает
  • stopped — процесс остановлен
  • failed — процесс упал (перезапуск отключён или исчерпан)
  • restarting — процесс ожидает перезапуска (отображается мигающим в Web UI)
  • starting — процесс запускается
  • stopping — процесс останавливается
  • completed — oneshot-процесс завершился успешно

Шаблоны процессов

Встроенные шаблоны для автоматической конфигурации:

Тип Команда Паттерн аргументов Проверка готовности Префиксы
SharedMemory uniset2-smemory --smemory-id ${name} corba:${name} SharedMemory, SM_, SMemory
UNetExchange uniset2-unetexchange --unet-name ${name} corba:${name} UNet, UNetExchange
MBTCPMaster uniset2-mbtcpmaster --mbtcp-name ${name} corba:${name} MBTCPMaster, MBTCP, ModbusTCP
MBTCPMultiMaster uniset2-mbtcpmultimaster --mbtcp-name ${name} corba:${name} MBMultiMaster, MBTCPMulti
MBSlave uniset2-mbslave --mbs-name ${name} corba:${name} MBSlave, ModbusSlave
RTUExchange uniset2-rtuexchange --rs-name ${name} corba:${name} RTU, RTUExchange
OPCUAServer uniset2-opcua-server --opcua-name ${name} corba:${name} OPCUAServer, OPCUASrv
OPCUAExchange uniset2-opcua-exchange --opcua-name ${name} corba:${name} OPCUAExchange, OPCUAClient
MQTTPublisher uniset2-mqttpublisher --mqtt-name ${name} corba:${name} MQTT, MQTTPublisher
LogDB uniset2-logdb --logdb-name ${name} нет LogDB
IOControl uniset2-iocontrol --io-name ${name} corba:${name} IOControl, IO_
BackendClickHouse uniset2-backend-clickhouse --clickhouse-name ${name} corba:${name} ClickHouse, BackendClickHouse
UWebSocketGate uniset2-uwebsocket-gate --ws-name ${name} corba:${name} WebSocket, UWebSocket

Примечание: Все процессы являются критическими по умолчанию. Используйте ignoreFail="true" для процессов, падение которых не должно останавливать launcher.

Placeholder ${name} заменяется на имя процесса.

Автоопределение Naming Service

Launcher автоматически определяет, нужен ли Naming Service (omniNames), на основе параметра конфигурации localIOR:

  • localIOR=0 (по умолчанию): Naming Service нужен — процессы используют CORBA Naming Service
  • localIOR=1: Naming Service не нужен — процессы используют локальные IOR-файлы

Это влияет на вывод режима --runlist.

Режим Dry-Run

Используйте --runlist или --dry-run чтобы увидеть что будет запущено без реального запуска процессов:

uniset2-launcher --confile configure.xml --localNode Node1 --runlist

Пример вывода:

=== Launcher Run List for Node1 ===
Naming Service: REQUIRED (localIOR=0)
Group 1: sharedmemory (depends: naming)
[1] SharedMemory
Type: SharedMemory
Command: uniset2-smemory --smemory-id SharedMemory
Ready: corba:SharedMemory (timeout: 10000ms)
Group 2: exchanges (depends: sharedmemory)
[2] UNetExchange1
Type: UNetExchange
Command: uniset2-unetexchange --unet-name UNetExchange1
Ready: corba:UNetExchange1 (timeout: 10000ms)
[3] LogDB
Type: LogDB
Command: uniset2-logdb --logdb-name LogDB
ignoreFail: yes
Skipped (nodeFilter mismatch):
- MBTCPMaster1 (nodeFilter: Node3)
Total: 3 processes to start

Web UI

При запуске с --http-port доступен веб-интерфейс для мониторинга и управления процессами.

Launcher Web UI

Доступ к Web UI

# Открытый доступ (только просмотр)
uniset2-launcher --http-port 8080 --confile config.xml --localNode Node1
# С авторизацией для управления
uniset2-launcher --http-port 8080 --control-token secret123 --confile config.xml --localNode Node1

Откройте в браузере: http://localhost:8080/ или http://localhost:8080/ui

Возможности Web UI

  • Просмотр списка процессов и их состояния (running, stopped, failed)
  • Просмотр PID и группы каждого процесса
  • Управление процессами: restart, stop, start (если задан --control-token)
  • Автоматическое обновление статуса каждые 5 секунд
  • Сохранение токена авторизации в localStorage браузера

Кастомизация

Используйте --html-template для указания собственного HTML-шаблона:

uniset2-launcher --html-template /path/to/custom.html ...

Доступные placeholder'ы в шаблоне:

  • {{NODE_NAME}} — имя текущего узла
  • {{API_URL}} — базовый URL API (например http://localhost:8080)
  • {{CONTROL_ENABLED}}true если задан control-token, иначе false

Авторизация HTTP API

Launcher поддерживает двухуровневую Bearer-токен авторизацию.

Уровни доступа

Опция Назначение
--read-token TOKEN Токен для чтения (Web UI, GET запросы к API)
--control-token TOKEN Токен для управления (POST restart/stop/start)

Режимы работы

Открытый доступ (по умолчанию):

uniset2-launcher --http-port 8080 ...
  • GET запросы: открыты
  • POST операции: запрещены (403 Forbidden)

Только управление защищено:

uniset2-launcher --http-port 8080 --control-token secret123 ...
  • GET запросы: открыты
  • POST операции: требуют Authorization: Bearer secret123

Полная авторизация:

uniset2-launcher --http-port 8080 --read-token viewer --control-token admin ...
  • GET запросы: требуют Authorization: Bearer viewer
  • POST операции: требуют Authorization: Bearer admin

Пример запроса с авторизацией

# Чтение статуса (если задан read-token)
curl -H "Authorization: Bearer viewer" http://localhost:8080/api/v2/launcher/status
# Перезапуск процесса
curl -X POST -H "Authorization: Bearer admin" \
http://localhost:8080/api/v2/launcher/process/SharedMemory/restart

REST API

Когда указан --http-port, доступны следующие endpoints. Launcher использует HTTP API v2.

Безопасность HTTP API

Для ограничения доступа к HTTP API используйте whitelist/blacklist:

# Только из локальной сети
uniset2-launcher --http-port 8080 --http-whitelist "192.168.1.0/24,10.0.0.0/8"
# Заблокировать конкретные IP
uniset2-launcher --http-port 8080 --http-blacklist "192.168.1.100,172.16.0.10-172.16.0.20"

Поддерживаемые форматы:

  • CIDR нотация: 192.168.1.0/24, 10.0.0.0/8
  • Конкретный IP: 192.168.1.100
  • Диапазон IP: 172.16.0.10-172.16.0.20

Правила:

  • Blacklist проверяется первым — если IP в blacklist, запрос отклоняется
  • Если whitelist не пустой, IP должен быть в whitelist для доступа
  • Пустой whitelist означает "разрешить всем" (кроме blacklist)

GET /api/v2/launcher

Получить статус всех процессов.

{
"node": "Node1",
"processes": [
{
"name": "SharedMemory",
"state": "running",
"pid": 1234,
"group": "sharedmemory",
"critical": true,
"skip": false,
"manual": false,
"restartCount": 0
},
{
"name": "ModbusMaster",
"state": "stopped",
"pid": 0,
"group": "exchanges",
"critical": false,
"skip": true,
"manual": false,
"restartCount": 0
}
],
"allRunning": true,
"anyCriticalFailed": false
}

GET /api/v2/launcher/status

Синоним для /api/v2/launcher.

GET /api/v2/launcher/processes

Получить список всех процессов с подробной информацией.

GET /api/v2/launcher/process/{name}

Получить статус конкретного процесса.

GET / и GET /ui

Веб-интерфейс для управления процессами. См. раздел Web UI.

GET /launcher-app.js

JavaScript-файл для веб-интерфейса.

POST /api/v2/launcher/process/{name}/restart

Перезапустить процесс. Требует --control-token.

{
"process": "UNetExchange",
"success": true
}

POST /api/v2/launcher/process/{name}/stop

Остановить процесс. Требует --control-token.

{
"process": "UNetExchange",
"success": true
}

POST /api/v2/launcher/process/{name}/start

Запустить остановленный процесс. Требует --control-token.

{
"process": "UNetExchange",
"success": true
}

POST /api/v2/launcher/restart-all

Перезапустить все работающие процессы. Требует --control-token.

{
"success": true,
"message": "Restart all initiated"
}

Перезапускаются только:

  • Процессы со статусом running, failed, restarting
  • Не пропущенные (skip=false)
  • Соответствующие текущему узлу (nodeFilter)
  • Manual-процессы только если были запущены

GET /api/v2/launcher/health

Проверка состояния для Docker/Kubernetes.

{
"status": "healthy",
"allRunning": true,
"anyCriticalFailed": false
}

Возвращает HTTP 200 если здоров, 503 если нет.

GET /api/v2/launcher/groups

Получить группы процессов.

GET /api/v2/launcher/help

Получить справку по доступным командам API.

Автозапуск omniNames

По умолчанию (если не указан --localIOR), Launcher автоматически:

  1. Запускает omniNames на порту UID+52809 (если не запущен)
  2. Создаёт репозиторий через uniset2-admin --create
  3. Останавливает omniNames при завершении (только если сам запустил)

Примеры

# Минимальный запуск (auto-порт по умолчанию)
uniset2-launcher --confile configure.xml
# Явный порт
uniset2-launcher --confile configure.xml --uniset-port 2809
# Без omniNames (localIOR режим)
uniset2-launcher --confile configure.xml --localIOR
# Без создания репозитория (уже существует)
uniset2-launcher --confile configure.xml --disable-admin-create

Формула auto-порта

port = UID + 52809

Для UID=1000 → порт 53809 Для UID=1001 → порт 53810

Это позволяет нескольким пользователям на одном сервере запускать проекты без конфликтов.

Каталог логов omniNames

По умолчанию: $TMPDIR/omniORB или $HOME/tmp/omniORB

Можно переопределить: --omni-logdir /path/to/logs

Переменные окружения

Следующие переменные устанавливаются автоматически и могут использоваться в аргументах процессов:

  • ${CONFFILE} — Путь к файлу конфигурации
  • ${NODE_NAME} — Имя локального узла

Дополнительные переменные можно определить в секции <Environment>.

Завершение процессов

При остановке (Ctrl+C, SIGTERM, REST API stop) Launcher корректно завершает все процессы.

Завершение дерева процессов

При остановке процесса Launcher завершает всё дерево процессов — родительский процесс и все его дочерние процессы (внуки, правнуки и т.д.). Это гарантирует, что не останется "зомби"-процессов или "осиротевших" дочерних процессов.

Алгоритм:

  1. Отправка SIGTERM всем процессам в дереве (от листьев к корню)
  2. Ожидание --stop-timeout миллисекунд
  3. Если процессы ещё живы — отправка SIGKILL всем оставшимся

Пример: Если запущен bash-скрипт, который порождает несколько подпроцессов:

ProcessManager -> bash_script.sh -> subprocess1
-> subprocess2
-> subprocess3

При остановке bash_script.sh будут завершены также subprocess1, subprocess2, subprocess3.

Таймаут остановки

Параметр --stop-timeout (по умолчанию: 5000 мс) определяет время ожидания graceful shutdown перед принудительным завершением:

# Ждать 10 секунд перед SIGKILL
uniset2-launcher --stop-timeout 10000 --confile config.xml

Для процессов с длительной процедурой завершения (flush буферов, закрытие соединений) рекомендуется увеличить таймаут.

Порядок остановки

При завершении Launcher'а:

  1. Останавливаются процессы в обратном порядке групп (сначала exchanges, затем sharedmemory, затем naming)
  2. Каждый процесс получает SIGTERM → ожидание → SIGKILL (если нужно)
  3. omniNames останавливается последним (если был запущен Launcher'ом)

Интеграция с systemd

При установке пакета в $(datadir)/uniset2/ размещается шаблон uniset2-launcher.service.template. Скопируйте его и настройте:

cp /usr/share/uniset2/uniset2-launcher.service.template \
/etc/systemd/system/uniset2-launcher.service
# Отредактируйте файл, замените @CONFFILE@, @NODE_NAME@, @HTTP_PORT@
systemctl daemon-reload
systemctl enable --now uniset2-launcher

Пример unit-файла:

[Unit]
Description=UniSet2 Launcher
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/uniset2-launcher \
--confile /etc/uniset2/configure.xml \
--localNode Node1 \
--http-port 8080 \
--stop-timeout 10000
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
[Install]
WantedBy=multi-user.target

Для нескольких нод можно использовать шаблон с i:

# /etc/systemd/system/uniset2-launcher@.service
ExecStart=/usr/bin/uniset2-launcher --confile /etc/uniset2/%i/configure.xml --localNode %i

Установка: systemctl enable uniset2-launcher@Node1

Пример Docker

ENTRYPOINT ["uniset2-launcher", "--confile", "/app/configure.xml"]
CMD ["--localNode", "Node1", "--http-port", "8080"]
# docker-compose.yml
services:
node1:
image: uniset2
command: ["--localNode", "Node1"]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/api/v2/launcher/health"]
interval: 10s
timeout: 5s
retries: 3

Сборка

Launcher собирается как часть расширений UniSet2:

./autogen.sh
make
make install

Устанавливаются следующие файлы:

  • /usr/bin/uniset2-launcher — Основной исполняемый файл
  • /usr/share/uniset2/launcher.html — HTML-шаблон Web UI
  • /usr/share/uniset2/launcher-app.js — JavaScript Web UI