(medium) scheduler.py/trigger_cian_backfill_run: при протухших cookies next_run_at не сдвигается → verify_session бьёт по Cian каждые 60с #1522

Closed
opened 2026-06-15 05:59:12 +00:00 by bot-backend · 1 comment
Collaborator

Severity: medium · Категория: logic · Файл: tradein-mvp/backend/app/services/scheduler.py:327-368

scheduler.py:331-348 — оба early-return по cookies (return None на строках 333 и 348) выполняются ДО _claim_run (строка 350), а _claim_run — единственное место, где next_run_at сдвигается на завтра (UPDATE scrape_schedules SET next_run_at=:next_at, строки 191-201). get_due_schedules (1008) переотбирает schedule WHERE next_run_at <= NOW() на каждом тике scheduler_loop (SCHEDULER_TICK_SEC=60, строка 73), и каждый тик заново вызывает load_session + verify_session, который делает реальный HTTP GET к Cian (cian_session.py:123, session.get(_VALUATION_TEST_URL) через curl_cffi chrome120 + mobile-proxy). Импакт: пока оператор вручную не зальёт свежие cookies, бэкенд раз в минуту круглосуточно долбит Cian — burn proxy-квоты + риск TLS/bot-бана. Чинить: при истёкших/отсутствующих cookies всё равно сдвигать next_run_at (например, отдельным UPDATE compute_next_run_at без создания run, либо backoff-интервалом), чтобы не переотбирать schedule каждый тик.

Почему баг: next_run_at сдвигается только внутри _claim_run (scheduler.py:187-201), а оба early-return по cookies (строки 332 и 348) происходят раньше. get_due_schedules (998-1015) фильтрует WHERE next_run_at IS NULL OR next_run_at <= NOW(), так что просроченный schedule переотбирается каждый тик. verify_session (cian_session.py:97) — внешний proxied HTTP GET к Cian. Для других source это самокорректируется (running-run skip → _claim_run потом всё равно сдвинет next_run_at), а для cian pre-check ничего никогда не двигает дату.

Как чинить: При skip из-за cookies всё равно сдвигать next_run_at (например на короткий backoff в N часов или на следующее окно), либо делать verify-pre-check не каждый тик, а по cooldown. Можно вынести compute_next_run_at + UPDATE scrape_schedules в отдельный helper и звать его в обоих early-return.


deep-audit «армия ботов 2» · verify+harden, confidence 0.9 · unit U126

**Severity:** medium · **Категория:** logic · **Файл:** `tradein-mvp/backend/app/services/scheduler.py:327-368` scheduler.py:331-348 — оба early-return по cookies (return None на строках 333 и 348) выполняются ДО _claim_run (строка 350), а _claim_run — единственное место, где next_run_at сдвигается на завтра (UPDATE scrape_schedules SET next_run_at=:next_at, строки 191-201). get_due_schedules (1008) переотбирает schedule WHERE next_run_at <= NOW() на каждом тике scheduler_loop (SCHEDULER_TICK_SEC=60, строка 73), и каждый тик заново вызывает load_session + verify_session, который делает реальный HTTP GET к Cian (cian_session.py:123, session.get(_VALUATION_TEST_URL) через curl_cffi chrome120 + mobile-proxy). Импакт: пока оператор вручную не зальёт свежие cookies, бэкенд раз в минуту круглосуточно долбит Cian — burn proxy-квоты + риск TLS/bot-бана. Чинить: при истёкших/отсутствующих cookies всё равно сдвигать next_run_at (например, отдельным UPDATE compute_next_run_at без создания run, либо backoff-интервалом), чтобы не переотбирать schedule каждый тик. **Почему баг:** next_run_at сдвигается только внутри _claim_run (scheduler.py:187-201), а оба early-return по cookies (строки 332 и 348) происходят раньше. get_due_schedules (998-1015) фильтрует WHERE next_run_at IS NULL OR next_run_at <= NOW(), так что просроченный schedule переотбирается каждый тик. verify_session (cian_session.py:97) — внешний proxied HTTP GET к Cian. Для других source это самокорректируется (running-run skip → _claim_run потом всё равно сдвинет next_run_at), а для cian pre-check ничего никогда не двигает дату. **Как чинить:** При skip из-за cookies всё равно сдвигать next_run_at (например на короткий backoff в N часов или на следующее окно), либо делать verify-pre-check не каждый тик, а по cooldown. Можно вынести compute_next_run_at + UPDATE scrape_schedules в отдельный helper и звать его в обоих early-return. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.9 · unit U126</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:59:12 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:02:17 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода (git show forgejo/main): scheduler.py:trigger_cian_backfill_run — два early-return ДО _claim_run: if cookies is None: return None и if state is None: ... return None (после await verify_session(cookies)). _claim_run (:151) — единственное место, где next_run_at сдвигается (UPDATE scrape_schedules SET ... next_run_at = :next_at ... :191-201). get_due_schedules (:998-1009) переотбирает WHERE next_run_at IS NULL OR next_run_at <= NOW(); SCHEDULER_TICK_SEC = 60 (:73).

Корень: При протухших/отсутствующих cookies оба return происходят до _claim_run, значит next_run_at не двигается. Просроченный schedule переотбирается каждый тик → каждые 60с заново load_session + await verify_session (реальный proxied HTTP GET к Cian через cian_session.py). Для других source self-correcting (running-skip → _claim_run всё равно сдвинет дату), для cian pre-check не двигает ничего.

Что править:

  • При skip из-за cookies всё равно сдвигать next_run_at (отдельным UPDATE scrape_schedules через compute_next_run_at, без создания run — короткий backoff N часов / следующее окно).
  • Либо вынести compute_next_run_at + UPDATE scrape_schedules в helper и звать в обоих early-return.
  • Либо делать verify-pre-check по cooldown, а не каждый тик.

Что посмотреть:

  • Код: scheduler.py:trigger_cian_backfill_run (early-returns), _claim_run:151-205, compute_next_run_at:77, get_due_schedules:998; cian_session.py:load_session/verify_session (proxied GET к _VALUATION_TEST_URL). Тест: schedule с протухшими cookies → next_run_at сдвинут, verify не зовётся каждый тик.
  • Vault: релевантных заметок не найдено.

Примечание: верификация против forgejo/main (рабочая ветка feat/cian-city-sweep-schedule трогает scheduler.py).

**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода (git show forgejo/main):** `scheduler.py:trigger_cian_backfill_run` — два early-return ДО `_claim_run`: `if cookies is None: return None` и `if state is None: ... return None` (после `await verify_session(cookies)`). `_claim_run` (`:151`) — единственное место, где `next_run_at` сдвигается (`UPDATE scrape_schedules SET ... next_run_at = :next_at ...` `:191-201`). `get_due_schedules` (`:998-1009`) переотбирает `WHERE next_run_at IS NULL OR next_run_at <= NOW()`; `SCHEDULER_TICK_SEC = 60` (`:73`). **Корень:** При протухших/отсутствующих cookies оба return происходят до `_claim_run`, значит `next_run_at` не двигается. Просроченный schedule переотбирается каждый тик → каждые 60с заново `load_session` + `await verify_session` (реальный proxied HTTP GET к Cian через `cian_session.py`). Для других source self-correcting (running-skip → `_claim_run` всё равно сдвинет дату), для cian pre-check не двигает ничего. **Что править:** - При skip из-за cookies всё равно сдвигать `next_run_at` (отдельным `UPDATE scrape_schedules` через `compute_next_run_at`, без создания run — короткий backoff N часов / следующее окно). - Либо вынести `compute_next_run_at` + `UPDATE scrape_schedules` в helper и звать в обоих early-return. - Либо делать verify-pre-check по cooldown, а не каждый тик. **Что посмотреть:** - Код: `scheduler.py:trigger_cian_backfill_run` (early-returns), `_claim_run:151-205`, `compute_next_run_at:77`, `get_due_schedules:998`; `cian_session.py:load_session`/`verify_session` (proxied GET к `_VALUATION_TEST_URL`). Тест: schedule с протухшими cookies → `next_run_at` сдвинут, verify не зовётся каждый тик. - Vault: релевантных заметок не найдено. Примечание: верификация против `forgejo/main` (рабочая ветка `feat/cian-city-sweep-schedule` трогает scheduler.py).
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#1522
No description provided.