Конкурентные scheduler-тики одного source (redeploy-overlap старого+нового контейнера / 2 реплики) оба проходили has_running_run pre-check и запускали ДВОЙНОЙ city-sweep → 2x rate к Avito/Cian → бан скрапера. Path A: transaction-scoped pg_try_advisory_xact_lock(hashtext(source)) после pre-check сериализует claim; non-blocking (lock занят → return None). Под локом double-checked has_running_run (running мог появиться в окне pre-check→lock). Лок авто-снимается на commit/rollback. Path B (partial unique index WHERE status='running') отклонён: миграция могла упасть на deploy если dirty-данные уже содержат >=2 running-строк на source (ровно то, что баг и создаёт) — рискованно перед demo. Tests: double-call→один run; lock unavailable→skip; running-under-lock→rollback+skip. |
||
|---|---|---|
| .. | ||
| api | ||
| core | ||
| observability | ||
| schemas | ||
| services | ||
| tasks | ||
| __init__.py | ||
| main.py | ||