ops: scripts/safe-restart.sh — рестарт демона лестницы только в тихое окно (без убийства живых LLM-воркеров; закрывает инцидент из e-260929234911)

This commit is contained in:
Simbiot Harness 2026-09-30 02:32:15 +00:00
parent 76aa204f2b
commit 5935ece4ec

39
scripts/safe-restart.sh Executable file
View file

@ -0,0 +1,39 @@
#!/bin/bash
# t-260929210755 / закрытие эскалации e-260929234911: рестарт демона лестницы
# БЕЗ убийства живых LLM-воркеров (рестарт при живом воркере = застрявшая
# running-задача, тот самый инцидент). Ждём «тихого окна» — нет процессов
# harness/_llm_worker.py, с подтверждением 3с, потом systemctl restart.
#
# Гарантия на гонку «проверил → стартовал новый воркер → рестарт»: orphan-requeue
# (commit 42743f9) возвращает running-задачи с мёртвым воркером в очередь —
# даже худший случай не теряет работу, просто повторит её.
#
# Использование: scripts/safe-restart.sh [max_wait_sec] (по умолчанию 3600)
set -u
MAX_WAIT="${1:-3600}"
LOG="${SIMBIOT_RESTART_LOG:-/tmp/simbiot-safe-restart.log}"
SERVICE="${SIMBIOT_SERVICE:-simbiot-harness}"
# якорь в конец cmdline: не матчит sh -c команды, которые лишь УПОМИНАют воркера
PAT='/harness/_llm_worker\.py$'
deadline=$(( $(date +%s) + MAX_WAIT ))
echo "[$(date -u '+%F %T')] safe-restart: ждём тихое окно (макс ${MAX_WAIT}s), сервис ${SERVICE}" >> "$LOG"
while :; do
if ! pgrep -f "$PAT" > /dev/null; then
sleep 3 # окно должно быть устойчивым
if ! pgrep -f "$PAT" > /dev/null; then
echo "[$(date -u '+%F %T')] safe-restart: тихое окно поймано" >> "$LOG"
break
fi
fi
if [ "$(date +%s)" -ge "$deadline" ]; then
echo "[$(date -u '+%F %T')] safe-restart: тихого окна нет ${MAX_WAIT}s — рестарт всё равно (orphan-requeue подхватит)" >> "$LOG"
break
fi
sleep 5
done
if systemctl restart "$SERVICE"; then
echo "[$(date -u '+%F %T')] safe-restart: демон ${SERVICE} перезапущен" >> "$LOG"
else
echo "[$(date -u '+%F %T')] safe-restart: FAIL — systemctl restart ${SERVICE}" >> "$LOG"
exit 1
fi