Проблема
Реальный N+1 в проекте — не SQL (SQLite in-process дешёвый), а docker exec. QuarantineService.listForMailboxes / purge (src/domain/quarantine/service.ts:43-54,84-94) делают по одному серийному doveadm-exec на каждый ящик. Админская страница карантина и ночной purge — O(mailboxes) контейнерных exec'ов. На сотнях ящиков это минуты wall-time.
Это первый по очереди user-visible scalability-cliff.
Фикс
- Bounded concurrency: батчить через
Promise.allSettled с лимитом (напр. 4-way), либо
- один вызов
doveadm -A (all-users) вместо цикла.
Связано с извлечением общего docker-exec с таймаутом (отдельный issue) — без таймаута один зависший doveadm в цикле держит весь запрос.
Проблема
Реальный N+1 в проекте — не SQL (SQLite in-process дешёвый), а docker exec.
QuarantineService.listForMailboxes/purge(src/domain/quarantine/service.ts:43-54,84-94) делают по одному серийномуdoveadm-exec на каждый ящик. Админская страница карантина и ночной purge — O(mailboxes) контейнерных exec'ов. На сотнях ящиков это минуты wall-time.Это первый по очереди user-visible scalability-cliff.
Фикс
Promise.allSettledс лимитом (напр. 4-way), либоdoveadm -A(all-users) вместо цикла.Связано с извлечением общего
docker-execс таймаутом (отдельный issue) — без таймаута один зависшийdoveadmв цикле держит весь запрос.