Documentation
¶
Overview ¶
Package etcd is a pure-Go (CGO=0), MRI-faithful reimplementation of the Ruby etcdv3 gem's client surface for etcd v3.
It does not reimplement the etcd protocol. It consumes the official pure-Go client go.etcd.io/etcd/client/v3 as its transport and layers the ergonomics and result/error model of the etcdv3 gem on top: Client.Get / Put / Del / Exists (single, range and prefix), Watch, lease grant / keep-alive / revoke / ttl, Transaction (compare / success / failure), and a lease-backed Lock / Unlock mirroring etcd's concurrency recipe. Maintenance (Members, Status) is exposed too.
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 logic testable against a deterministic in-memory transport with no external etcd and no cgo, so the suite reaches 100% coverage on every arch under qemu, mirroring the go-ruby-nats embedded-server-plus-deterministic-fallback split. A separate live suite (build tag "live") drives an in-process embedded etcd for real round-trip validation on native lanes.
Ruby mapping ¶
conn = Etcdv3.new(endpoints: 'http://127.0.0.1:2379') => etcd.New(etcd.Config{Endpoints: ...})
conn.put('k', 'v') => c.Put(ctx, "k", "v")
conn.get('k') => c.Get(ctx, "k")
conn.get('k', range_end: 'l') => c.Get(ctx, "k", etcd.WithRange("l"))
conn.del('k') => c.Del(ctx, "k")
conn.exists?('k') => c.Exists(ctx, "k")
conn.watch('k') { |events| ... } => 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(key) => c.Lock(ctx, "n", 10) / c.Unlock(ctx, lk)
Index ¶
- Variables
- type Client
- func (c *Client) Close() error
- func (c *Client) Del(ctx context.Context, key string, opts ...OpOption) (*DelResult, error)
- func (c *Client) Exists(ctx context.Context, key string) (bool, error)
- func (c *Client) Get(ctx context.Context, key string, opts ...OpOption) (*GetResult, error)
- func (c *Client) LeaseGrant(ctx context.Context, ttl int64) (*LeaseGrantResult, error)
- func (c *Client) LeaseKeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResult, error)
- func (c *Client) LeaseRevoke(ctx context.Context, id LeaseID) (*LeaseRevokeResult, error)
- func (c *Client) LeaseTTL(ctx context.Context, id LeaseID, withKeys bool) (*LeaseTTLResult, error)
- func (c *Client) Lock(ctx context.Context, name string, ttl int64) (*Lock, error)
- func (c *Client) Members(ctx context.Context) (*MembersResult, error)
- func (c *Client) Put(ctx context.Context, key, value string, opts ...OpOption) (*PutResult, error)
- func (c *Client) Status(ctx context.Context, endpoint string) (*StatusResult, error)
- func (c *Client) Transaction(ctx context.Context, build func(*Txn)) (*TxnResult, error)
- func (c *Client) Unlock(ctx context.Context, lk *Lock) error
- func (c *Client) Watch(ctx context.Context, key string, opts ...OpOption) <-chan WatchResult
- func (c *Client) WatchBlock(ctx context.Context, fn func([]Event), key string, opts ...OpOption) error
- type Cmp
- type Config
- type Connection
- type DelResult
- type Error
- type Event
- type EventType
- type GetResult
- type Header
- type KeyValue
- type Kvs
- type LeaseGrantResult
- type LeaseID
- type LeaseKeepAliveResult
- type LeaseRevokeResult
- type LeaseTTLResult
- type Lock
- type Member
- type MembersResult
- type Op
- type OpOption
- func WithCountOnly() OpOption
- func WithFromKey() OpOption
- func WithKeysOnly() OpOption
- func WithLease(id LeaseID) OpOption
- func WithLimit(n int64) OpOption
- func WithPrefix() OpOption
- func WithPrevKV() OpOption
- func WithRange(end string) OpOption
- func WithRevision(rev int64) OpOption
- func WithSerializable() OpOption
- type PutResult
- type StatusResult
- type Txn
- type TxnOpResult
- type TxnResult
- type WatchResult
Constants ¶
This section is empty.
Variables ¶
var ( ErrCanceled = &Error{Code: codes.Canceled, Name: "Canceled"} ErrUnknown = &Error{Code: codes.Unknown, Name: "Unknown"} ErrInvalidArgument = &Error{Code: codes.InvalidArgument, Name: "InvalidArgument"} ErrDeadlineExceeded = &Error{Code: codes.DeadlineExceeded, Name: "DeadlineExceeded"} ErrNotFound = &Error{Code: codes.NotFound, Name: "NotFound"} ErrAlreadyExists = &Error{Code: codes.AlreadyExists, Name: "AlreadyExists"} ErrPermissionDenied = &Error{Code: codes.PermissionDenied, Name: "PermissionDenied"} ErrResourceExhausted = &Error{Code: codes.ResourceExhausted, Name: "ResourceExhausted"} ErrFailedPrecondition = &Error{Code: codes.FailedPrecondition, Name: "FailedPrecondition"} ErrAborted = &Error{Code: codes.Aborted, Name: "Aborted"} ErrOutOfRange = &Error{Code: codes.OutOfRange, Name: "OutOfRange"} ErrUnimplemented = &Error{Code: codes.Unimplemented, Name: "Unimplemented"} ErrInternal = &Error{Code: codes.Internal, Name: "Internal"} ErrDataLoss = &Error{Code: codes.DataLoss, Name: "DataLoss"} ErrUnauthenticated = &Error{Code: codes.Unauthenticated, Name: "Unauthenticated"} )
The etcdv3 error tree: one sentinel per gRPC status code. Compare with errors.Is, e.g. errors.Is(err, etcd.ErrNotFound).
var ErrEmptyKey = &Error{Code: codes.InvalidArgument, Name: "InvalidArgument", Message: "empty key"}
ErrEmptyKey is returned by key operations when the key is empty; etcd rejects empty keys, and rejecting them locally avoids a needless round trip.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an etcd v3 client bound to a transport seam. It mirrors the etcdv3 gem's connection object: it builds requests, drives them over the transport, and maps responses to the gem's result and error model. Construct one with New; the zero value is not usable.
func New ¶
New connects to etcd using cfg and returns a Client. It builds a *clientv3.Client, which dials lazily, so New returns without a round trip and fails only on a malformed configuration (for example no endpoints).
func (*Client) Del ¶
Del deletes key, or a range/prefix when a range option is supplied. It mirrors the gem's #del.
func (*Client) Exists ¶
Exists reports whether key is present. It mirrors the gem's #exists? and uses a count-only read so it transfers no values.
func (*Client) Get ¶
Get retrieves key, or a range/prefix of keys when a range option is supplied. It mirrors the gem's #get.
func (*Client) LeaseGrant ¶
LeaseGrant grants a lease that expires after ttl seconds. It mirrors the gem's #lease_grant.
func (*Client) LeaseKeepAliveOnce ¶
LeaseKeepAliveOnce renews a lease once. It mirrors the gem's #lease_keep_alive_once (the single-shot keep-alive).
func (*Client) LeaseRevoke ¶
LeaseRevoke revokes a lease, deleting every key attached to it. It mirrors the gem's #lease_revoke.
func (*Client) LeaseTTL ¶
LeaseTTL returns a lease's remaining TTL. When withKeys is true the result also lists the keys attached to the lease. It mirrors the gem's #lease_ttl.
func (*Client) Lock ¶
Lock acquires a distributed lock named name, backed by a lease of ttl seconds, and blocks until it is held (or ctx is cancelled). It mirrors the etcdv3 gem's #lock and implements etcd's concurrency recipe: each caller writes a unique, lease-bound key under name/, and the caller whose key has the lowest creation revision owns the lock; later waiters watch the key just ahead of them until it is deleted.
func (*Client) Members ¶
func (c *Client) Members(ctx context.Context) (*MembersResult, error)
Members lists the cluster's members. It mirrors the gem's #members.
func (*Client) Put ¶
Put stores value at key. It mirrors the gem's #put and honours WithLease and WithPrevKV.
func (*Client) Status ¶
Status returns the status of the member serving endpoint. It mirrors the gem's #status.
func (*Client) Transaction ¶
Transaction runs an etcd transaction. The callback fills a Txn with comparisons (If) and success/failure operations (Then/Else); the transaction is then committed atomically. It mirrors the gem's #transaction block.
func (*Client) Unlock ¶
Unlock releases a held lock: it deletes the ownership key and revokes its lease. It mirrors the gem's #unlock.
func (*Client) Watch ¶
Watch watches key (or a prefix/range when a range option is supplied) and returns a channel of event batches. The channel closes when ctx is cancelled or the watch is otherwise terminated. It mirrors the gem's #watch.
func (*Client) WatchBlock ¶
func (c *Client) WatchBlock(ctx context.Context, fn func([]Event), key string, opts ...OpOption) error
WatchBlock watches key and invokes fn with each non-empty batch of events, mirroring the etcdv3 gem's block form conn.watch(key) { |events| ... }. It blocks until the watch ends (ctx cancelled) or a terminal error arrives, returning that error (nil on a clean, ctx-driven stop).
type Cmp ¶
Cmp is a transaction comparison, built with Compare over one of Value, Version, CreateRevision, ModRevision or LeaseValue. It aliases the clientv3 type so it drives the real transaction machinery directly.
func Compare ¶
Compare finishes a comparison: op is one of "=", "!=", ">", "<" and v is the value to compare the target against. It mirrors the gem's comparison DSL.
func CreateRevision ¶
CreateRevision targets a key's creation revision in a comparison.
func LeaseValue ¶
LeaseValue targets a key's attached lease in a comparison.
func ModRevision ¶
ModRevision targets a key's modification revision in a comparison.
type Config ¶
type Config struct {
// Endpoints is the list of etcd endpoints to connect to, e.g.
// []string{"127.0.0.1:2379"}. A leading "http://" or "https://" scheme is
// accepted and normalised away, matching the gem which takes a URL.
Endpoints []string
// DialTimeout bounds the initial connection. Zero uses the client default.
DialTimeout time.Duration
// Username and Password enable authenticated connections when both are set.
Username string
Password string
// TLS, when set, is applied to the underlying client for https endpoints.
// It is optional; nil means plaintext (or scheme-derived) transport.
TLS *tls.Config
}
Config configures a Client. The fields mirror the keywords the etcdv3 gem's Etcdv3.new accepts that affect connecting to the cluster.
type Connection ¶
type Connection = Client
Connection is the etcdv3 gem's name for the object Etcdv3.new returns. It is an alias for Client.
type DelResult ¶
DelResult is the reply to Del: how many keys were deleted and, when requested, their previous values.
type Error ¶
type Error struct {
// Code is the gRPC status code etcd reported.
Code codes.Code
// Name is the etcdv3 error-class name for Code (e.g. "NotFound").
Name string
// Message is the human-readable detail from the status.
Message string
// contains filtered or unexported fields
}
Error is the base of the etcdv3 error tree. It carries the gRPC status code etcd returned and mirrors the etcdv3 gem, whose error classes map one-to-one onto the gRPC status codes. Match a specific kind with errors.Is against one of the exported sentinels (for example ErrNotFound); the match is by status code, so a wrapped Error compares equal to its sentinel.
func (*Error) Is ¶
Is reports whether target is an *Error with the same status code, so the exported sentinels match any Error of the same kind regardless of message.
func (*Error) Unwrap ¶
Unwrap exposes the underlying transport error for errors.Unwrap.
type Event ¶
Event is a single watch event: the change kind and the affected key-value, with the previous value when the watch requested it.
type GetResult ¶
GetResult is the reply to Get: the matched key-values plus range metadata. It mirrors the gem's range response (kvs, count, more).
type KeyValue ¶
type KeyValue struct {
Key string
Value string
CreateRevision int64
ModRevision int64
Version int64
Lease int64
}
KeyValue mirrors the gem's key-value object (etcd's mvccpb.KeyValue).
type Kvs ¶
type Kvs = []KeyValue
Kvs is a convenience alias for a slice of KeyValue, echoing the gem's naming.
type LeaseGrantResult ¶
LeaseGrantResult is the reply to LeaseGrant. ID is the granted lease id (the gem's lease['ID']); Error is set when the grant partially failed.
type LeaseID ¶
LeaseID identifies a lease. It mirrors clientv3.LeaseID (an int64), which is the "ID" the etcdv3 gem returns from lease_grant.
type LeaseKeepAliveResult ¶
LeaseKeepAliveResult is the reply to a single keep-alive.
type LeaseRevokeResult ¶
type LeaseRevokeResult struct {
Header Header
}
LeaseRevokeResult is the reply to LeaseRevoke.
type LeaseTTLResult ¶
LeaseTTLResult is the reply to LeaseTTL: the remaining and granted TTLs and, when requested, the keys attached to the lease.
type Lock ¶
type Lock struct {
// Key is the lock-ownership key this holder created.
Key string
// Lease is the lease attached to Key; revoking it also frees the lock.
Lease LeaseID
// contains filtered or unexported fields
}
Lock is a held distributed lock: the key that represents ownership and the lease that keeps it alive. Release it with Client.Unlock.
type MembersResult ¶
MembersResult is the reply to Members.
type Op ¶
Op is a transaction operation, built with OpGet, OpPut or OpDelete.
type OpOption ¶
OpOption is a per-operation option (prefix, range, lease, ...). It aliases the clientv3 option type so options compose across this package and the underlying client.
func WithCountOnly ¶
func WithCountOnly() OpOption
WithCountOnly asks a read to return only the count of matching keys.
func WithFromKey ¶
func WithFromKey() OpOption
WithFromKey makes the operation act on all keys >= key.
func WithKeysOnly ¶
func WithKeysOnly() OpOption
WithKeysOnly asks a read to return keys without their values.
func WithPrefix ¶
func WithPrefix() OpOption
WithPrefix makes the operation act on every key sharing the given key as a prefix (the gem's range/prefix reads and deletes).
func WithPrevKV ¶
func WithPrevKV() OpOption
WithPrevKV asks Put/Del to return the previous key-value; mirrors prev_kv.
func WithRange ¶
WithRange makes the operation act on the half-open range [key, end); mirrors the gem's range_end keyword.
func WithRevision ¶
WithRevision reads keys as of the given store revision.
func WithSerializable ¶
func WithSerializable() OpOption
WithSerializable permits a serializable (non-linearizable) read.
type PutResult ¶
PutResult is the reply to Put; PrevKv is set when the previous value was requested (or surfaced by the backend).
type StatusResult ¶
type StatusResult struct {
Header Header
Version string
DbSize int64
Leader uint64
RaftIndex uint64
RaftTerm uint64
IsLearner bool
}
StatusResult is the reply to Status: a member's version, database size and raft state. It mirrors the gem's #status.
type Txn ¶
type Txn struct {
// contains filtered or unexported fields
}
Txn accumulates a transaction's comparisons and branches. It is filled inside the callback passed to Client.Transaction and mirrors the gem's txn object whose compare / success / failure lists map to Txn.If / Txn.Then / Txn.Else.
type TxnOpResult ¶
TxnOpResult is one operation's reply within a transaction; exactly one of the fields is set, matching the operation kind.
type TxnResult ¶
type TxnResult struct {
Header Header
Succeeded bool
Responses []TxnOpResult
}
TxnResult is the reply to a transaction: whether the comparisons held and the per-operation replies of the branch that ran.
