Skip to content

Repository files navigation

go-ruby-etcd/etcd

etcd — go-ruby-etcd

Docs License Go Coverage

A pure-Go (no cgo), MRI-faithful reimplementation of the Ruby etcdv3 gem's client surface for etcd v3 — the ergonomics and result/error model of the gem's connection object (get / put / del / exists?, watch, lease_*, transaction, lock / unlock) layered over the official pure-Go etcd client.

It does not reimplement the etcd protocol. It consumes go.etcd.io/etcd/client/v3 as its transport and maps the gem's API onto it, so a static, CGO=0 binary talks to a real etcd cluster.

It is the etcd backend for go-embedded-ruby, but is a standalone, reusable module — a sibling of go-ruby-redis and go-ruby-pg.

Transport is a host seam. A Client drives an injected transport whose method set is satisfied directly by *clientv3.Client (no adapter). This makes every method's request-building and response-mapping logic testable against a deterministic in-memory transport — no external etcd, no cgo — so the suite holds 100% coverage on every arch under qemu, mirroring the go-ruby-nats embedded-server-plus-deterministic-fallback split. A separate live suite drives a real in-process embedded etcd for round-trip validation on native lanes.

Features

  • KVGet (single, range via WithRange, prefix via WithPrefix, WithFromKey, WithLimit, WithRevision, WithSerializable, WithKeysOnly, WithCountOnly), Put (WithLease, WithPrevKV), Del, Exists.
  • WatchWatch (channel form) and WatchBlock (the gem's watch(key){ |events| } block form) over keys, prefixes and ranges, with PUT / DELETE events and previous values.
  • LeaseLeaseGrant, LeaseKeepAliveOnce, LeaseRevoke, LeaseTTL (with attached keys).
  • TransactionTransaction { If / Then / Else } mapping the gem's compare / success / failure lists, with Compare over Value / Version / CreateRevision / ModRevision / LeaseValue.
  • LockLock / Unlock, a lease-backed mutex implementing etcd's concurrency recipe (lowest creation-revision owns; waiters watch their predecessor).
  • MaintenanceMembers, Status.
  • Errors — an Etcdv3-style error tree (Error + one sentinel per gRPC status code) matchable with errors.Is.

Usage

c, err := etcd.New(etcd.Config{Endpoints: []string{"127.0.0.1:2379"}})
if err != nil {
	log.Fatal(err)
}
defer c.Close()

ctx := context.Background()
c.Put(ctx, "/service/a", "up", etcd.WithLease(lease.ID))
gr, _ := c.Get(ctx, "/service/", etcd.WithPrefix())
for _, kv := range gr.Kvs {
	fmt.Println(kv.Key, "=", kv.Value)
}

c.Transaction(ctx, func(t *etcd.Txn) {
	t.If(etcd.Compare(etcd.Value("/service/a"), "=", "up")).
		Then(etcd.OpPut("/service/a", "draining")).
		Else(etcd.OpGet("/service/a"))
})

Ruby mapping

etcdv3 gem go-ruby-etcd/etcd
Etcdv3.new(endpoints: ...) etcd.New(etcd.Config{Endpoints: ...})
conn.put('k', 'v') c.Put(ctx, "k", "v")
conn.get('k', range_end: 'l') c.Get(ctx, "k", etcd.WithRange("l"))
conn.del('k') / conn.exists?('k') c.Del(ctx, "k") / c.Exists(ctx, "k")
conn.watch('k') { |evs| ... } c.WatchBlock(ctx, fn, "k") / c.Watch(ctx, "k")
conn.lease_grant(10) c.LeaseGrant(ctx, 10)
conn.transaction { |t| ... } c.Transaction(ctx, func(t *etcd.Txn){ ... })
conn.lock('n', 10) / conn.unlock c.Lock(ctx, "n", 10) / c.Unlock(ctx, lk)

Tests & coverage

The default suite runs with -race and holds 100% statement coverage on all three host OSes and the six supported 64-bit architectures (amd64, arm64, riscv64, loong64, ppc64le and big-endian s390x), driving the full client logic against a deterministic in-memory transport with no external etcd:

go test -race -cover ./...

The live/ nested module validates real round-trip behaviour against an in-process embedded etcd (native-only; kept out of the main module so its large dependency tree never enters this go.mod):

cd live && go test ./...

License

BSD-3-Clause — see LICENSE. Copyright (c) 2026, the go-ruby-etcd/etcd authors.

WebAssembly

Unlike the rest of the go-ruby family, this library does not target WebAssembly: its backing engine — go.etcd.io/bbolt (memory-mapped files + file locking) — relies on mmap and native filesystem syscalls that the js/wasm and wasip1/wasm sandboxes do not provide. It ships for the six 64-bit native/qemu arches only.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages