feat: log-tailer offset persistence + in-flight L2 rate-limit accounting (code-review.md § Phase 3)
- logtail: persist the read position (offset + fingerprint of the log's first 512 bytes) in a new logtail_state table (migration 0003) and resume from it on start, so delivery lines written while the panel was down are parsed instead of skipped and their send-log rows no longer stay "queued" forever. Fingerprint mismatch (rotated/recreated while down) reads the file from the start — re-parsing is idempotent; a first-ever start with nothing stored still begins at end-of-file. Writes are throttled to one per 5s, forced on rotation and shutdown. - milter: count messages that passed the level-2 check but have not reached the send log yet (internal/milter/inflight.go), so concurrent SMTP sessions cannot each spend the same last slot. A literal count+insert transaction, as the review suggested, is not possible: the count happens at MAIL FROM and the insert at end-of-message. Reservations are released after the insert, on ABORT, and after a 10-minute TTL — a client that drops mid-transaction must not be able to hold a slot, since the limiter is fail-open by design. Docs: architecture.md (log tailer, persistence, L2 counting), security.md and roadmap.md (restart gap closed, container recreate remains), CHANGELOG, progress.md, code-review.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+6
-4
@@ -118,10 +118,12 @@ Hardening сверх обязательного (security-заголовки, п
|
||||
безвозвратно нерасшифровываемый архив хуже незашифрованного: пароль SelfPost
|
||||
не хранит. Триггером сделать шифрование обязательным считать появление
|
||||
второго администратора (тогда «кто скачал» перестаёт быть одним человеком).
|
||||
- **Send-log может навсегда остаться `queued` после рестарта панели или
|
||||
пересоздания контейнера.** Log-tailer стартует с конца `mail.log`; файл не в
|
||||
`/data` и теряется при recreate. Rename-ротация это не лечит. См. [architecture.md](architecture.md)
|
||||
§ Log tailer — known gaps.
|
||||
- **Send-log может навсегда остаться `queued` после пересоздания контейнера.**
|
||||
Рестарт панели это больше не вызывает: log-tailer сохраняет позицию чтения
|
||||
(`logtail_state`, миграция `0003`) и после старта дочитывает хвост, написанный
|
||||
пока панель лежала. Но `mail.log` живёт не в `/data` и теряется вместе с
|
||||
контейнером — строки, чьи delivery-строки были только в нём, останутся
|
||||
`queued`. См. [architecture.md](architecture.md) § Log tailer.
|
||||
|
||||
## ADR: CSRF через проверку Origin, без токенов
|
||||
|
||||
|
||||
Reference in New Issue
Block a user