Multiple Backends
Choose the storage that fits your stack: JDBC/MySQL with optimistic locking, Redis with atomic Lua scripts and pub/sub, or Zookeeper via Apache Curator.
Easy-to-use distributed lock services for Kotlin and Java applications -- backed by JDBC, Redis, or Zookeeper.
Simba uses a cooperative leader-election protocol. Each contender competes for a named mutex, and the winner becomes the owner for a configurable TTL window. When the TTL expires, a transition period begins during which the current owner can renew its lease preferentially. Non-owner contenders wake up with random jitter to reduce collision.
stateDiagram-v2
[*] --> Free
Free --> Acquired : contender acquires
Acquired --> Renewing : TTL about to expire
Renewing --> Acquired : guard succeeds
Renewing --> Transition : TTL expired
Transition --> Acquired : owner renews grace
Transition --> Free : transition expires
Free --> Acquired : other contender acquiresSimba offers three levels of abstraction so you can pick the one that best matches your use case:
graph TD
subgraph sg_21 ["API Levels"]
direction TB
H["AbstractScheduler<br>Leader-gated periodic jobs"]
L["SimbaLocker<br>RAII / try-with-resources"]
M["MutexContender<br>Callback-based"]
end
M -->|"wraps"| L
L -->|"wraps"| H
style H fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
style L fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
style M fill:#2d333b,stroke:#6d5dfc,color:#e6edf3graph TD
subgraph sg_22 ["simba-core"]
direction TB
CS["MutexContendService<br>+ MutexContendServiceFactory"]
end
subgraph sg_23 ["Backends"]
direction TB
J["simba-jdbc<br>JDBC / MySQL"]
R["simba-spring-redis<br>Redis Lua + Pub/Sub"]
Z["simba-zookeeper<br>Apache Curator"]
end
CS --> J
CS --> R
CS --> Z
style CS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
style J fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
style R fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
style Z fill:#2d333b,stroke:#6d5dfc,color:#e6edf3class MyContender : AbstractMutexContender("my-mutex") {
override fun onAcquired(mutexState: MutexState) {
println("I am the owner!")
}
override fun onReleased(mutexState: MutexState) {
println("Lost leadership.")
}
}