- Ya
- 4 Septemba 2026, 21:01 UTC
- Mwandishi
- Kamo
- Ahadi ya
- c649e79
Nine of EmailService's ten scheduled sweeps have a shared effect and now take a named lease before running. The most consequential is CampaignDispatcher: at two pods without a lock, every recipient of every running campaign would have received a duplicate. ReminderSchedulerService is the same shape for meeting reminders, and **************** for snoozed notifications. The tenth, **************** is deliberately NOT locked. It walks the mailboxes watched by clients connected to THIS pod and nudges the ones nothing is pushing, so it has to run everywhere — locking it would freeze the unread badge for every member whose WebSocket landed on a pod that is not the leaseholder. @Transactional is now on both the scheduled wrapper and the locked body in ReminderSchedulerService and SyncService. The outer one is what actually applies (the body is reached through a this:: reference, which never goes through the Spring proxy); the inner is declared because that is the method issuing the @Modifying query, which is what the arch ratchet reads — and the ratchet caught exactly this when the annotation was only on the wrapper. replicas 1 -> 2. 590 tests, one pre-existing failure unrelated to this change **************** fails identically on origin/main).