- Shipped
- September 4, 2026 at 8:30 PM UTC
- Author
- Kamo
- Commit
- 7fc9377
There is no ShedLock anywhere on this platform and there never has been. All 97 @Scheduled sweeps across 18 services are correct only because each service runs exactly one pod. Scale any of them and the sweep runs twice a tick — two meeting reminders in a member's inbox, two chat-email notices, two passes over a billing period. Those single-replica deployments were not merely un-scaled; the replica count was load bearing, and the code says so in three places already. **************** lease, body) runs a body on exactly one pod. AN EXPLICIT CALL, NOT AN ANNOTATION. @SingletonTask beside @Scheduled is the obvious design and it is a trap here: it would be applied by an AOP proxy, and a proxy is bypassed entirely when a method is reached from inside the same bean — the Spring self-invocation problem this codebase has been caught by five separate times. A sweep that silently lost its lock and ran on every pod is that same failure, and nothing would reveal it until a customer counted their emails. Taking the lock by calling it cannot be bypassed by how the method was reached, and it greps. REDIS, NOT THE DATABASE. A lock table needs DDL, and DDL on this cluster makes every service answer 500 'schema version mismatch' for ~15 minutes while Hikari connections age out. Paying a platform-wide outage to install the machinery that prevents platform-wide outages is a bad trade when Redis is already deployed. FAILS CLOSED. If Redis is unreachable the task is skipped, not run: for work that sends email or moves money, running twice is worse than not running, and the next tick retries. Release is a compare-and-delete script so a body that overran its lease cannot delete a lock another pod has since taken, and overrunning is logged at ERROR because nothing else would reveal it. Where a service has no Redis the fallback runs the body always — exactly what the code does today, so adopting this never changes behaviour on its own — and warns at startup. The manifest guard in CI refuses replicas > 1 for a service in that state. 7 tests; full suite 2710 green.