github.com/tailscale/tailetc (go): Package tailetc implements an total-memory-cache etcd v3 client implemented by tailing (watching) an entire etcd.  The client maintains a complete copy of the etcd database in memory, with values decoded into Go objects.  It presents a simplified transaction model that assumes that multiple writers will not be contending on keys. When you call tx.Get or tx.Put, your Tx records the current etcd global revision. When you tx.Commit, if some newer revision of any key touched by Tx is in etcd then the commit will fail.  Contention failures are reported as ErrTxStale from tx.Commit. Failures may be reported sooner as tx.Get or tx.Put errors, but the tx error is sticky, that is, if you ignore those errors the eventual error from tx.Commit will have ErrTxStale in its error chain.  The Tx.Commit method waits before successfully returning until DB has caught up with the etcd global revision of the transaction. This ensures that sequential happen in the strict database sequence. So if you serve a REST API from a single *etcd.DB instance, then the API will behave as users expect it to.  If you know only one thing about this etcd client, know this:  Everything else should follow a programmer's intuition for an in-memory map guarded by a RWMutex.  We take advantage of etcd's watch model to maintain a *decoded* value cache of the entire database in memory. This means that querying a value is extremely cheap. Issuing tx.Get(key) involves no more work than holding a mutex read lock, reading from a map, and cloning the value.  The etcd watch is then exposed to the user of *etcd.DB via the WatchFunc. This lets users maintain in-memory higher-level indexes into the etcd database that respond to external commits. WatchFunc is called while the database lock is held, so a WatchFunc implementation cannot synchronously issue transactions.  The cache in etcd.DB is very careful not to copy objects both into and out of the cache so that users of the etcd.DB cannot get pointers directly into the memory inside the cache. This means over-copying. Users can control precisely how much copying is done, and how, by providing a CloneFunc implementation.  The general ownership semantics are: objects are copied as soon as they are passed to etcd, and any memory returned by etcd is owned by the caller.
Keywords: etcd|etcd-client