fix(ci): ожидание докер-лока оставляет след в логе (#2950) #2958

Merged
bot-backend merged 1 commit from fix/2950-lock-wait-observable into main 2026-08-20 08:44:11 +00:00
3 changed files with 51 additions and 8 deletions

View file

@ -655,10 +655,21 @@ jobs:
# прикрывать, что и требуется. Ожидание ограничено: не дождались за
# 900с — падаем с внятным сообщением, а не молча ждём вечно.
exec 9>/var/lock/gendesign-docker-deploy.lock
if ! flock -w 900 9; then
echo "ERROR: не дождался лока докер-деплоя за 900с."
echo " Кто держит: ssh на хост, затем fuser -v /var/lock/gendesign-docker-deploy.lock"
exit 1
# Сначала неблокирующая попытка — чтобы ОЖИДАНИЕ оставляло след в логе.
# Без этого работающий лок ненаблюдаем: flock при успехе молчит, и отличить
# «второй деплой дождался первого» от «они просто разошлись по времени»
# нельзя — а именно это и есть критерий приёмки #2950.
if flock -n 9; then
echo "→ докер-лок свободен, взят сразу"
else
echo "→ докер-лок занят соседним деплоем, жду (до 900с)…"
lock_wait_started=$(date +%s)
if ! flock -w 900 9; then
echo "ERROR: не дождался лока докер-деплоя за 900с."
echo " Кто держит: ssh на хост, затем fuser -v /var/lock/gendesign-docker-deploy.lock"
exit 1
fi
echo "→ докер-лок получен через $(( $(date +%s) - lock_wait_started ))с ожидания"
fi
cd /opt/gendesign

View file

@ -501,10 +501,21 @@ jobs:
# прикрывать, что и требуется. Ожидание ограничено: не дождались за
# 900с — падаем с внятным сообщением, а не молча ждём вечно.
exec 9>/var/lock/gendesign-docker-deploy.lock
if ! flock -w 900 9; then
echo "ERROR: не дождался лока докер-деплоя за 900с."
echo " Кто держит: ssh на хост, затем fuser -v /var/lock/gendesign-docker-deploy.lock"
exit 1
# Сначала неблокирующая попытка — чтобы ОЖИДАНИЕ оставляло след в логе.
# Без этого работающий лок ненаблюдаем: flock при успехе молчит, и отличить
# «второй деплой дождался первого» от «они просто разошлись по времени»
# нельзя — а именно это и есть критерий приёмки #2950.
if flock -n 9; then
echo "→ докер-лок свободен, взят сразу"
else
echo "→ докер-лок занят соседним деплоем, жду (до 900с)…"
lock_wait_started=$(date +%s)
if ! flock -w 900 9; then
echo "ERROR: не дождался лока докер-деплоя за 900с."
echo " Кто держит: ssh на хост, затем fuser -v /var/lock/gendesign-docker-deploy.lock"
exit 1
fi
echo "→ докер-лок получен через $(( $(date +%s) - lock_wait_started ))с ожидания"
fi
cd /opt/gendesign

View file

@ -69,6 +69,27 @@ def test_prod_deploy_takes_the_host_lock(name: str) -> None:
)
@pytest.mark.parametrize("name", PROD_DEPLOYS)
def test_lock_wait_leaves_a_trace(name: str) -> None:
"""Ожидание лока видно в логе — иначе работающий лок ненаблюдаем.
`flock` при успехе молчит. Если брать лок сразу блокирующим вызовом, отличить
«второй деплой дождался первого» от «они просто разошлись по времени» нельзя
а это и есть критерий приёмки #2950. Поэтому сначала неблокирующая попытка, и
при занятом локе в лог уходит и факт ожидания, и его длительность.
"""
script = _deploy_script(name)
assert "flock -n" in script, (
f"{name}: лок берётся сразу блокирующим вызовом — ожидание не попадёт в лог, "
"и проверить, что взаимное исключение сработало, будет нечем"
)
assert "жду" in script, f"{name}: нет строки об ожидании лока"
assert "с ожидания" in script, (
f"{name}: не печатается длительность ожидания — без неё непонятно, "
"ждал деплой две секунды или четверть часа"
)
@pytest.mark.parametrize("name", PROD_DEPLOYS)
def test_lock_wait_is_bounded_and_loud(name: str) -> None:
"""Ожидание ограничено и провал слышен: молча ждать вечно — не вариант."""