fix(scrape_kn): Redis-lock owner-token + resume retry on lock_held (#1216) #1255
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#1255
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/scrape-kn-redis-lock-owner-token"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes #1216 (P2 concurrency, prod). Два бага в Redis-lock'е
scrape_kn:value="1"без owner-токена → release удаляет чужой lock когда sweep дольше TTL.resume_kn_runskip без retry, run теряется до недельного beat.Bug
No owner token + tight TTL:
_LOCK_TTL_SECONDS=30мин = заявленная длительность sweep'а. Если sweep >TTL → lock истекает, второй sweep стартует → первый при завершенииr.deleteсносит ЧУЖОЙ lock → третий параллельный.Stale lock + terminal skip: SIGKILL/redeploy mid-sweep —
finallyне выполняется, lock живёт до 30 мин в Redis с volume.worker_readyметит run'zombie'и enqueue'итresume_kn_runБЕЗ countdown. Ловит lock_held → возвращает{skipped: True}(безraise) → max_retries инертен. Никто больше не подхватывает: scan ищет только'running', nspd_cleanup_zombies — не про kn. Run мёртв до недельного beat.Fix
uuid.uuid4().hex(32 chars hex). Release через LuaEVALсо скриптом check-and-delete:if GET == ARGV[1] then DEL else 0 end. Inline literal (однократный вызов в finally,register_scriptлишний).lock_held→raise self.retry(countdown=300, max_retries=12)— 5 мин × 12 = ~1 час окно для подхвата вместо silent skip.scrape_kn_region(scheduled) намеренно остаётсяskipped— beat поднимет в следующий weekly tick (другая семантика, не зомби).Test plan
evalне дёргается при failed acquire, TTL=2700, contract Lua-скрипта, retry-not-skip, run_not_found всё ещё skipped, scheduled by-design skipped.pytest tests/workers/tasks/test_scrape_kn.py→ 11 passed.pytest -k scrape_kn→ 16 passed, 1 skipped.ruff check→ clean.Closes #1216