[Fable 5][P3] nspd_geo: except (NspdLiteError, Exception) проглатывает SoftTimeLimitExceeded — 6-часовой лимит таски не работает #1235

Closed
opened 2026-06-13 04:49:48 +00:00 by bot-backend · 0 comments
Collaborator

Из армейского ревью Claude Fable 5 (2026-06-11)

Confirmed by 2/2 адверсариальных верификатора, severity P3 (correctness), confidence 0.6.

Файл

backend/app/workers/tasks/nspd_geo.py:486

Evidence (цитата кода)

except (NspdLiteError, Exception) as e:
    logger.warning("fetch failed for %s: %s", cad, e)
    _log(db, job_id, "warn", "fetch_fail", str(e)[:300], cad_num=cad)

Why bug

process_nspd_geo_job имеет только soft_time_limit=6ч (hard time_limit не задан ни на таске, ни глобально — подтверждено docstring forecast.py). SoftTimeLimitExceeded наследует Exception и почти наверняка прилетает внутри try-блока (fetch до 15с + rate-sleep — почти весь wall-clock цикла) → ловится этой веткой как «fetch failed», помечает таргет и продолжает цикл. Celery кидает сигнал один раз → таска работает неограниченно дольше 6ч, бессрочно занимая слот geo-очереди.

Suggested fix

Перехватывать SoftTimeLimitExceeded отдельно ДО generic-ветки (re-raise или _finish_job('paused') + return) и/или задать hard time_limit чуть больше soft (как у harvest_quarter в nspd_sync.py).

Verify notes

  • [real/P3] Декоратор задаёт только soft_time_limit=6h; hard time_limit нет ни на таске, ни в celery_app.conf (только timezone+beat_schedule); prod-worker — prefork. >95% wall-clock итерации — fetch(timeout=15s)+time.sleep(rate_ms) внутри inner try → SoftTimeLimitExceeded(Exception) ловится except (NspdLiteError, Exception) на line 486 как fetch_fail (attempts+1, commit) и цикл продолжается. Сигнал прилетает один раз → крупный job (>6ч по построению) работает неограниченно, занимая 1 из 8 слотов воркера.
  • [real/P3] Защиты нет: celery_app.py не задаёт task_time_limit; prod worker без --time-limit/--pool (prefork → soft limit реально кидается, один раз). SoftTimeLimitExceeded наследует Exception; почти весь wall-clock итерации (fetch timeout=15 + rate-sleep) внутри try → ловится на :486 как fetch_fail, цикл продолжается; heartbeat остаётся свежим → cleanup_zombies не вмешается. Проект сам признал класс бага: nspd_sync.py получил hard time_limit=900 в re-review PR #260 именно за это; nspd_geo — soft-only.

Provenance

  • Finders: workers
  • Confidence: 0.6
  • Originally batched at: main@d796027
## Из армейского ревью Claude Fable 5 (2026-06-11) Confirmed by 2/2 адверсариальных верификатора, severity **P3** (correctness), confidence 0.6. ## Файл [`backend/app/workers/tasks/nspd_geo.py:486`](backend/app/workers/tasks/nspd_geo.py:486) ## Evidence (цитата кода) ``` except (NspdLiteError, Exception) as e: logger.warning("fetch failed for %s: %s", cad, e) _log(db, job_id, "warn", "fetch_fail", str(e)[:300], cad_num=cad) ``` ## Why bug process_nspd_geo_job имеет только soft_time_limit=6ч (hard time_limit не задан ни на таске, ни глобально — подтверждено docstring forecast.py). SoftTimeLimitExceeded наследует Exception и почти наверняка прилетает внутри try-блока (fetch до 15с + rate-sleep — почти весь wall-clock цикла) → ловится этой веткой как «fetch failed», помечает таргет и продолжает цикл. Celery кидает сигнал один раз → таска работает неограниченно дольше 6ч, бессрочно занимая слот geo-очереди. ## Suggested fix Перехватывать SoftTimeLimitExceeded отдельно ДО generic-ветки (re-raise или _finish_job('paused') + return) и/или задать hard time_limit чуть больше soft (как у harvest_quarter в nspd_sync.py). ## Verify notes - [real/P3] Декоратор задаёт только soft_time_limit=6h; hard time_limit нет ни на таске, ни в celery_app.conf (только timezone+beat_schedule); prod-worker — prefork. >95% wall-clock итерации — fetch(timeout=15s)+time.sleep(rate_ms) внутри inner try → SoftTimeLimitExceeded(Exception) ловится except (NspdLiteError, Exception) на line 486 как fetch_fail (attempts+1, commit) и цикл продолжается. Сигнал прилетает один раз → крупный job (>6ч по построению) работает неограниченно, занимая 1 из 8 слотов воркера. - [real/P3] Защиты нет: celery_app.py не задаёт task_time_limit; prod worker без --time-limit/--pool (prefork → soft limit реально кидается, один раз). SoftTimeLimitExceeded наследует Exception; почти весь wall-clock итерации (fetch timeout=15 + rate-sleep) внутри try → ловится на :486 как fetch_fail, цикл продолжается; heartbeat остаётся свежим → cleanup_zombies не вмешается. Проект сам признал класс бага: nspd_sync.py получил hard time_limit=900 в re-review PR #260 именно за это; nspd_geo — soft-only. ## Provenance - Finders: `workers` - Confidence: 0.6 - Originally batched at: main@d796027
bot-backend added the
Fable 5 ревью
label 2026-06-13 04:49:48 +00:00
Sign in to join this conversation.
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#1235
No description provided.