A distributed lock, so a scheduled sweep can survive a second replica

Featurekamo-shared-library
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.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing