You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make newsletter delivery replay-safe and track per-recipient outcomes #81
Severity: P1 — newsletter delivery reliability. Confirmed in main 6722c6b and still present after hardening PR #77.
Post#send_newsletter checks finished_sending? before enqueue, but does not claim sending atomically. PublishPostJob#perform neither checks that flag nor records a unique delivery for each post/subscription: it delivers to every active subscriber on every invocation. Two queued jobs or a retry after partial progress can therefore send duplicates. Ordinary recipient errors are logged and the post is still marked finished, with no durable failed-recipient retry state. The existing EmailMessage history has no unique delivery key.
Evidence: an isolated regression with a published post and one synthetic subscriber, with delivery mocked, runs PublishPostJob twice. It observes two deliveries to the same subscription even though the first run sets finished_sending. No external email was sent. This is separate from subscriber confirmation idempotence (#29, addressed in #77) and fatal-exception handling (#24).
Define one delivery record/key per post and subscriber, with an atomic claim that prevents concurrent/duplicate jobs from both delivering it. Preserve a deliberate resend as an explicit separate operation.
Track pending, delivered, and failed recipients; derive completion from this state instead of marking all recipients finished after logged errors.
Handle provider-accepted-but-response-lost ambiguity explicitly: use provider idempotency if available or document recovery semantics. A database flag alone cannot promise exactly-once external delivery.
Test duplicate enqueue, concurrent workers, interruption after one accepted delivery, transient/permanent recipient failures, retry, unsubscribe/locked-author before delivery, and explicit resend. Use isolated mail/provider doubles in both modes.
Surface actionable delivery progress/failure counts without exposing subscriber addresses to other accounts.
Activity