fix(queue): убрать мёртвую очередь {search-queue} (#379) #380
Reference in New Issue
Block a user
Delete Branch "fix/379-remove-dead-search-queue"
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
Убираю мёртвую очередь
{search-queue}: продюсеры есть, консьюмера нет и не было (он живёт в EE-редакции Docmost). Поиск работает через DB tsvector-триггер и от очереди не зависит — очередь просто копила джобы (1902 залипших в Redis, первое реальное срабатывание алертаqueue-growingиз #355, сработал корректно). closes #379.Что убрано
@InjectQueue(SEARCH_QUEUE)+ всеsearchQueue.add(...)+ гейтisTypesense()(он оборачивал только search-энкью).page.listener.handlePageUpdatedделал ТОЛЬКО search-энкью → удалён вместе с@OnEvent(PAGE_UPDATED); остальные хендлеры сохранилиaiQueue.add.queue.module.ts) и инжект в метрики + запись{label:'search'}(metrics-bull.service.ts).QueueName.SEARCH_QUEUE+ 6 неиспользуемыхSEARCH_INDEX_*(grep-подтверждено). ОбщиеQueueJob(PAGE_*,SPACE_DELETED,WORKSPACE_DELETED— их юзают AI-очередь / embedding/history/notification процессоры) сохранены.Поиск (tsvector-триггер,
search.service) и WS-слушательPAGE_UPDATEDне тронуты.How verified
apps/servertsc --noEmit→ 0 ошибок;jest metrics embedding history.processor page-ws.listener→ 6 suites / 52 tests passed. Висячих ссылок на удалённые символы по всему репо нет. Внутреннее ревью — APPROVE (потерь не-поисковых сайд-эффектов нет;PAGE_UPDATED-событие сохраняет живого WS-консьюмера).Ops (за оператором, вне scope кода)
redis-cli --scan --pattern "bull:{search-queue}:*" | xargs -r redis-cli delbullmq_queue_depth{queue="search"}стабильно 0 (метрика больше не инжектит эту очередь).Вне scope
Другие мёртвые EE-константы (
SEARCH_REMOVE_*/TYPESENSE_FLUSH) оставил — их удаление не в scope #379.Checklist
The {search-queue} BullMQ queue had producers on every page/space/workspace change but NO consumer/@Processor — it lives in Docmost's EE edition (external search drivers), never in this fork. Search works independently via the pages tsvector DB trigger; the queue was pure dead weight, growing forever (1902 stuck jobs in Redis, the first real hit of the #355 queue-growing alert — which fired correctly). Remove the plumbing: - the 3 producers: drop @InjectQueue(SEARCH_QUEUE) + every searchQueue.add(...) from page/space/workspace.listener.ts (and the isTypesense() gate that only wrapped the search enqueue). page.listener.handlePageUpdated did ONLY the search enqueue, so its @OnEvent(PAGE_UPDATED) handler is removed; the other handlers keep their aiQueue.add. - the registration (queue.module.ts) and the metrics injection + 'search' depth-metric entry (metrics-bull.service.ts). - the constants: QueueName.SEARCH_QUEUE + the 6 unused SEARCH_INDEX_* QueueJob members (grep-confirmed unreferenced). Shared QueueJob members (PAGE_*, SPACE_DELETED, WORKSPACE_DELETED — used by the AI queue / embedding/history/notification processors) are kept. Search (tsvector trigger, search.service) and the PAGE_UPDATED websocket listener are untouched. Verified: apps/server tsc --noEmit 0 errors; 6 spec suites / 52 tests green. Ops (maintainer, out of code scope): one-time Redis cleanup `redis-cli --scan --pattern "bull:{search-queue}:*" | xargs -r redis-cli del`, then confirm bullmq_queue_depth{queue="search"} stays 0 (the metric no longer injects it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>🤖 Авто-ревью · #380 (fix(queue): убрать мёртвую очередь {search-queue} (#379)), голова
97bd554cВердикт: PASS ✅ — удаление чистое, полное и безопасное; поиск от очереди не зависит и продолжает работать. Ставлю review/approved.
Веер 9 аспектов (5 субагентов + 4 напрямую) — ни одного DO/ESCALATE. Всё сверено с кодом; ключевые утверждения PR подтверждены.
Что проверено (адверсариально)
database(environment.service.ts:305) ищет по колонкеpages.tsv(search.service.ts→ts_rank(tsv, to_tsquery(...))), аtsvподдерживается DB-триггеромpages_tsvector_trigger()(migrations/20240324T086800-pages-tsvector-trigger.ts+.../20250729T...-update-tsvector,BEFORE INSERT OR UPDATE ON pages). УдалённыйsearchQueue.addэтот путь никогда не питал. Объективка: jestsrc/core/search— 3 suites / 18 tests passed.ee/в репо отсутствует; ни@Processor({search-queue}), ни любого консьюмера нет. Продюсеры энкьюили в никуда (1902 залипших джоба — корректное срабатывание алертаqueue-growingиз #355). Typesense EE-гейтед и на запись, и на чтение (search.controller.tssearchTypesense→require('../../ee/typesense/...')→ бросаетBadRequestException, т.к.ee/нет), так что драйверtypesenseв этой сборке был сломан ДО PR и остаётся так же — PR лишь прекращает рост очереди. Поведение не изменено.handlePageUpdatedбезопасно.EventName.PAGE_UPDATEDпо-прежнему эмитится (page.repo.ts:177) и имеет живого консьюмера —ws/listeners/page-ws.listener.ts:78(@OnEvent(PAGE_UPDATED), WS-бродкаст rename/icon). Удалённый хендлер делал ТОЛЬКО search-энкью — других сайд-эффектов не потеряно (AI-энкью на PAGE_UPDATED и не было; на created/deleted/soft-deleted/restoredaiQueue.addсохранён).tsc -p tsconfig.build.json --noEmit— 0 ошибок. Ноль остаточных ссылок наSEARCH_QUEUE/searchQueue/SEARCH_INDEX_*по всему репо. DI консистентен:queue.module.tsрегистрирует 9 очередей =metrics-bullинжектит ровно те же 9 (массив{label,queue}выровнен, off-by-one нет);EnvironmentServiceкорректно убран из 3 листенеров (его единственное использование —isTypesense()— удалено) и корректно ОСТАВЛЕН вmetrics-bull(там он дляgetRedisUrl()). Ни одного повисшего импорта. Спеки на удалённые символы не ссылаются — сломанных тестов нет.Вне scope (кандидаты на отдельный issue, НЕ блокеры) + что судил напрямую
Вне scope (до-существующее, PR не ухудшает — на отдельный issue):
QueueJob.SEARCH_REMOVE_PAGE/ASSET/FACE+TYPESENSE_FLUSHоставлены. Проверено на родительском коммите (97bd554c^): они были орфанами уже до PR (только самоопределение, ноль продюсеров) — то есть это НЕ внесённая PR-ом несогласованность.SEARCH_INDEX_*убраны потому что это имена джобов удаляемой очереди;SEARCH_REMOVE_*/TYPESENSE_FLUSH— отдельные до-существующие орфаны, к продюсерам очереди не привязаны. Оставить их безвредно (плейн-строки enum, ни к чему не биндятся). Бонус: их строковые значения уже перепутаны (SEARCH_REMOVE_FACE='search-remove-comment') — тоже до-существующее. Стоит подмести отдельно.typesenseв CE-сборке:search.controller.tsвсё ещё роутит наsearchTypesense(бросает,ee/нет), аenvironment.validation.tsвсё ещё принимаетSEARCH_DRIVER='typesense'(@IsIn). До-существующее, PR не трогает и не ухудшает; решить судьбу throw-only typesense-пути — отдельной задачей.Судил напрямую (аспекты, тривиально чистые для dead-code-удаления): security — новой поверхности нет (только удаление); simplification — код стал проще; documentation — публичных API/доков не меняет; architecture — структурных решений нет, удаление изолировано в queue+listeners.
Веер 9 аспектов, все LGTM; DB-триггер и независимость поиска воспроизвёл сам (jest 18/18), tsc зелёный. Единственная заметка — до-существующие мёртвые константы — ниже DROP-floor и вне scope. Ветка чистая, можно мёржить.