Recipes¶
Each recipe is a coordination pattern built from etcd's primitives — leases, watches, and atomic transactions. They share a lifecycle and a failure model, both described in Core concepts.
The catalog¶
| Package | Recipes |
|---|---|
lock |
DistributedMutex, DistributedReadWriteLock, DistributedSemaphore |
election |
LeaderSelector, LeaderLatch, LeaderObserver, Participant |
barrier |
DistributedBarrier, DistributedBarrierWithCount, DistributedDoubleBarrier |
queue |
DistributedQueue, DistributedPriorityQueue, DistributedWorkQueue, TypedDistributedQueue<T>, TypedDistributedPriorityQueue<T> |
cache |
NodeCache<T>, PathChildrenCache, TypedPathChildrenCache<T> |
counter |
DistributedAtomicLong |
discovery |
ServiceDiscovery, ServiceRegistry, ServiceCache, ServiceProvider, ServiceInstance, ProviderStrategy |
keyvalue |
TransientKeyValue, TypedTransientKeyValue<T> |
common |
Kotlin extensions over jetcd; EtcdCodec<T> |
coroutines |
Suspending twins, Flow event surfaces |
Choosing one¶
I need one process to do this at a time.
A DistributedMutex if it is a short critical section around a specific
resource. A LeaderLatch if it is an ongoing role — a scheduler, a
compactor — that one instance should hold for as long as it stays healthy. The difference
is duration and intent: a lock guards a section, a leader owns a job.
I need at most N at a time.
DistributedSemaphore.
Many readers, occasional writer.
DistributedReadWriteLock.
Work must be done once, and survive a worker crash.
DistributedWorkQueue — at-least-once with visibility timeouts and dead
letters. Not DistributedQueue, which drops the item on the floor if a consumer dies
holding it.
Fan work out, order matters, losses tolerable.
DistributedQueue or DistributedPriorityQueue.
Everyone waits until everyone is ready. Barriers — simple for a gate someone opens, counted for an N-party rendezvous, double for enter-and-leave phase sync.
Read a value that changes, without hammering etcd.
NodeCache<T> for one key, PathChildrenCache for a prefix.
Both keep a local view current with a watch.
Find the instances of a service.
Service discovery — with ServiceProvider if you want
client-side load balancing and error ejection too.
Count something across processes.
DistributedAtomicLong.
Advertise something that disappears if my process dies.
TransientKeyValue.
What they share¶
- Constructors do no I/O. Work happens in
start()or on first use. Closeable.close()is idempotent; most takeuse { }.withXxx { }. Most have a scoped function that starts and closes for you.- Failures surface, they don't throw from worker threads.
exceptions, listeners, andconnectionState. See Core concepts. - Holds can be lost. See Leases and loss.
- Typed variants exist for queues, caches and key/values via
EtcdCodec<T>. - Suspending twins exist for nearly everything. See Coroutines.
- They are Java-usable. See the Java guide.
Composing them¶
The recipes are built on the same Kotlin extensions over jetcd that
you have, and they never hide the Client. Mixing a recipe with a raw transaction against
your own keys is normal and expected, not a workaround.
The EtcdRecipes facade is a convenience factory for the
common ones if you would rather not construct each type by hand.