fix(tradein/deploy): atomic recreate + graceful scraper drain + startup-reap (#1951) #2388

Merged
lekss361 merged 1 commit from fix/tradein-1951-deploy-atomicity into main 2026-07-04 06:49:07 +00:00
Owner

Summary

  • Атомарность: browser/backend/frontend/scraper пересоздаются в один docker compose up -d --no-deps $SERVICES вместо двух раздельных вызовов.
  • Graceful drain: перед recreate scraper — poll scrape_runs.status='running' до 5 мин (30×10s); WARNING+proceed на таймауте (существующий SIGTERM-drain + stop_grace_period 120s остаются финальной страховкой).
  • Startup-reap: orphaned running-строки (heartbeat старше DB-clock checkpoint'а, взятого прямо перед stop) помечаются cancelled сразу вместо ожидания 6h zombie-reaper'а. Реализовано ЦЕЛИКОМ в deploy-workflow (shell), НЕ в scheduler_main.py/scrapers — избегает коллизии с активной scraper_kit-миграцией (#2277).
  • Review fixup: tr -d '[:space:]' ломал внутренний пробел в timestamp-литерале (CAST(...AS timestamptz) молча падал на КАЖДОМ деплое) → заменено на sed-trim только leading/trailing. Drain-loop больше не путает неудачный psql-read с подтверждённым running_count=0 (иначе транзиентный docker-exec/DB glitch тихо пропускал весь drain-wait).

Test plan

  • YAML валиден (yaml.safe_load), docker compose config -q проходит
  • Live-repro обоих критических багов в throwaway postgres:16 контейнере (code-review) — подтверждена причина, подтверждён фикс
  • code-review: MAJOR (2 критических) → оба пофикшены, готово к смёржу
  • Post-deploy: сверить _manifest_applied/логи следующего деплоя на факт срабатывания startup-reap (если найдутся orphaned rows)

Refs #1951

## Summary - **Атомарность**: browser/backend/frontend/scraper пересоздаются в один `docker compose up -d --no-deps $SERVICES` вместо двух раздельных вызовов. - **Graceful drain**: перед recreate scraper — poll `scrape_runs.status='running'` до 5 мин (30×10s); WARNING+proceed на таймауте (существующий SIGTERM-drain + `stop_grace_period 120s` остаются финальной страховкой). - **Startup-reap**: orphaned running-строки (heartbeat старше DB-clock checkpoint'а, взятого прямо перед stop) помечаются `cancelled` сразу вместо ожидания 6h zombie-reaper'а. Реализовано ЦЕЛИКОМ в deploy-workflow (shell), НЕ в `scheduler_main.py`/scrapers — избегает коллизии с активной scraper_kit-миграцией (#2277). - **Review fixup**: `tr -d '[:space:]'` ломал внутренний пробел в timestamp-литерале (`CAST(...AS timestamptz)` молча падал на КАЖДОМ деплое) → заменено на `sed`-trim только leading/trailing. Drain-loop больше не путает неудачный psql-read с подтверждённым `running_count=0` (иначе транзиентный docker-exec/DB glitch тихо пропускал весь drain-wait). ## Test plan - [x] YAML валиден (`yaml.safe_load`), `docker compose config -q` проходит - [x] Live-repro обоих критических багов в throwaway `postgres:16` контейнере (code-review) — подтверждена причина, подтверждён фикс - [x] code-review: ❌MAJOR (2 критических) → оба пофикшены, готово к смёржу - [ ] Post-deploy: сверить `_manifest_applied`/логи следующего деплоя на факт срабатывания startup-reap (если найдутся orphaned rows) Refs #1951
lekss361 added 1 commit 2026-07-04 06:48:23 +00:00
fix(tradein/deploy): atomic recreate + graceful scraper drain + startup-reap (#1951)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
720e812dda
Atomicity: browser/backend/frontend/scraper recreated in one
docker compose up invocation instead of two sequential calls.

Graceful drain: before recreating scraper, poll scrape_runs for
running=0 up to 5min; WARNING+proceed on timeout (SIGTERM-drain
+ stop_grace_period + startup-reap below remain the safety net).

Startup-reap: mark orphaned running rows (heartbeat before a
DB-clock checkpoint taken right before stop) as cancelled instead
of waiting for the 6h zombie reaper. Implemented entirely in the
deploy workflow shell, not scheduler_main.py/scrapers, to avoid
touching files owned by the in-flight scraper_kit migration (#2277).

Review fixups: tr -d '[:space:]' was stripping the internal space
in the DB-clock timestamp literal (CAST(...timestamptz) failed
silently on every deploy) — switched to sed trim of leading/
trailing whitespace only. Drain-loop no longer conflates a failed
psql read with a confirmed running_count=0 (would have silently
skipped the drain wait on any transient docker-exec/DB hiccup).
lekss361 merged commit 9850bbde14 into main 2026-07-04 06:49:07 +00:00
lekss361 deleted branch fix/tradein-1951-deploy-atomicity 2026-07-04 06:49:08 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2388
No description provided.