Open-Source Wikis

/

etcd

/

Features

/

Distributed primitives

etcd-io/etcd

Distributed primitives

The repo ships several distributed primitives built on top of the core KV/Lease/Watch API: mutexes, leader elections, software-transactional-memory style transactions, and the v3lock/v3election gRPC services.

Building blocks

All client-side primitives are built on three observations:

  1. A lease dies if the holder dies — perfect basis for fencing.
  2. A txn with mod_revision == 0 is a "create only if absent" insert — the basis for mutual exclusion.
  3. Watch lets a waiter sleep until the contended state changes.

Mutex

Source: client/v3/concurrency/mutex.go.

sess, _ := concurrency.NewSession(cli)
defer sess.Close()
m := concurrency.NewMutex(sess, "/my-lock/")
_ = m.Lock(ctx)
defer m.Unlock(ctx)

Implementation:

  1. Session grants a lease and starts a keep-alive loop.
  2. Mutex.Lock performs a Txn{If(KeyMissing(key)).Then(Put(key, "", lease)).Else(Get(key))} against <prefix>/<lease-id>.
  3. If the key is created, the caller owns the lock.
  4. Otherwise the caller watches the predecessor key (the one with the largest revision smaller than its own) and waits for it to disappear.

This is the classic "queueing lock" pattern, optimized so contenders only wake up when the actual predecessor releases.

Election

Source: client/v3/concurrency/election.go.

Election.Campaign is a slight variant of Mutex.Lock that picks the lowest revision under the prefix as the leader; followers Observe() to find out who currently leads. Resign() removes the key. The same primitive backs etcdctl elect.

STM

Source: client/v3/concurrency/stm.go.

NewSTM lets you write code like:

_, _ = concurrency.NewSTM(cli, func(s concurrency.STM) error {
    a := s.Get("acct/A")
    b := s.Get("acct/B")
    s.Put("acct/A", subFunds(a, 10))
    s.Put("acct/B", addFunds(b, 10))
    return nil
})

Internally STM tracks every read and writes a single Txn whose If clause asserts that all read keys still have the observed mod_revision. On conflict it retries with exponential backoff.

v3lock and v3election

The same primitives are exposed as gRPC services so non-Go clients can use them:

  • server/etcdserver/api/v3lock/ exposes Lock / Unlock.
  • server/etcdserver/api/v3election/ exposes Campaign, Resign, Proclaim, Leader, Observe.

Both services run an in-process clientv3.Client (via server/etcdserver/api/v3client/) so the server is, at this layer, a client of itself. The implementation lives in lock.go / election.go of the respective packages.

leasing

client/v3/leasing/ provides a caching KV interface: each accessed key is leased to the local client, and reads/writes are served locally until another client revokes the lease. Useful for workloads with strong locality of reference.

namespace and mirror

  • client/v3/namespace/ wraps a clientv3.Client to transparently prefix every key — handy for multi-tenant deployments.
  • client/v3/mirror/ continuously copies a key range into another etcd cluster.

Cross-references

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Distributed primitives – etcd wiki | Factory