Documentation ¶
Overview ¶
clientv3 is the official Go etcd client for v3.
Create client using `clientv3.New`:
cli, err := clientv3.New(clientv3.Config{ Endpoints: []string{"localhost:12378", "localhost:22378", "localhost:32378"}, DialTimeout: 5 * time.Second, }) if err != nil { // handle error! } defer cli.Close()
Make sure to close the client after using it. If the client is not closed, the connection will have leaky goroutines.
To specify client request timeout, pass context.WithTimeout to APIs:
ctx, cancel := context.WithTimeout(context.Background(), timeout) resp, err := kvc.Put(ctx, "sample_key", "sample_value") cancel() if err != nil { // handle error! } // use the response
etcd client returns 2 types of errors:
- context error: canceled or deadline exceeded.
- gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/error.go.
Here is the example code to handle client errors:
resp, err := kvc.Put(ctx, "", "") if err != nil { if err == context.Canceled { // ctx is canceled by another routine } else if err == context.DeadlineExceeded { // ctx is attached with a deadline and it exceeded } else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok { // process (verr.Errors) } else { // bad cluster endpoints, which are not etcd servers } }
Example ¶
package main import ( "log" "time" "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" "github.com/coreos/etcd/clientv3" ) var ( dialTimeout = 5 * time.Second requestTimeout = 1 * time.Second endpoints = []string{"localhost:2378", "localhost:22378", "http://localhost:32380"} ) func main() { cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() // make sure to close the client _, err = cli.Put(context.TODO(), "foo", "bar") if err != nil { log.Fatal(err) } }
Output:
Index ¶
- Variables
- type Auth
- type AuthEnableResponse
- type Client
- type Cluster
- type Cmp
- type CompareResult
- type CompareTarget
- type Config
- type DefragmentResponse
- type DeleteResponse
- type EndpointDialer
- type GetResponse
- type KV
- type Lease
- type LeaseCreateResponse
- type LeaseID
- type LeaseKeepAliveResponse
- type LeaseRevokeResponse
- type Maintenance
- type Member
- type MemberAddResponse
- type MemberListResponse
- type MemberRemoveResponse
- type MemberUpdateResponse
- type Op
- type OpOption
- func WithFirstCreate() []OpOption
- func WithFirstKey() []OpOption
- func WithFirstRev() []OpOption
- func WithFromKey() OpOption
- func WithLastCreate() []OpOption
- func WithLastKey() []OpOption
- func WithLastRev() []OpOption
- func WithLease(leaseID LeaseID) OpOption
- func WithLimit(n int64) OpOption
- func WithPrefix() OpOption
- func WithProgressNotify() OpOption
- func WithRange(endKey string) OpOption
- func WithRev(rev int64) OpOption
- func WithSerializable() OpOption
- func WithSort(target SortTarget, order SortOrder) OpOption
- type OpResponse
- type PutResponse
- type SortOption
- type SortOrder
- type SortTarget
- type Txn
- type TxnResponse
- type WatchChan
- type WatchResponse
- type Watcher
Examples ¶
- Package
- Cluster (MemberAdd)
- Cluster (MemberLeader)
- Cluster (MemberList)
- Cluster (MemberRemove)
- Cluster (MemberUpdate)
- KV (Compact)
- KV (Delete)
- KV (Do)
- KV (Get)
- KV (GetSortedPrefix)
- KV (Put)
- KV (Txn)
- Lease (Create)
- Lease (KeepAlive)
- Lease (KeepAliveOnce)
- Lease (Revoke)
- Watcher (Watch)
- Watcher (WatchPrefix)
- Watcher (WatchProgressNotify)
Constants ¶
This section is empty.
Variables ¶
var (
ErrNoAvailableEndpoints = errors.New("etcdclient: no available endpoints")
)
Functions ¶
This section is empty.
Types ¶
type Auth ¶
type Auth interface { // AuthEnable enables auth of a etcd cluster. AuthEnable(ctx context.Context) (*AuthEnableResponse, error) }
type AuthEnableResponse ¶
type AuthEnableResponse pb.AuthEnableResponse
type Client ¶
type Client struct { Cluster KV Lease Watcher Auth Maintenance // contains filtered or unexported fields }
Client provides and manages an etcd v3 client session.
func NewFromURL ¶
NewFromURL creates a new etcdv3 client from a URL.
func (*Client) ActiveConnection ¶
func (c *Client) ActiveConnection() *grpc.ClientConn
ActiveConnection returns the current in-use connection
func (*Client) Ctx ¶
Ctx is a context for "out of band" messages (e.g., for sending "clean up" message when another context is canceled). It is canceled on client Close().
func (*Client) Dial ¶
func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error)
Dial establishes a connection for a given endpoint using the client's config
type Cluster ¶
type Cluster interface { // MemberList lists the current cluster membership. MemberList(ctx context.Context) (*MemberListResponse, error) // MemberLeader returns the current leader member. MemberLeader(ctx context.Context) (*Member, error) // MemberAdd adds a new member into the cluster. MemberAdd(ctx context.Context, peerAddrs []string) (*MemberAddResponse, error) // MemberRemove removes an existing member from the cluster. MemberRemove(ctx context.Context, id uint64) (*MemberRemoveResponse, error) // MemberUpdate updates the peer addresses of the member. MemberUpdate(ctx context.Context, id uint64, peerAddrs []string) (*MemberUpdateResponse, error) }
Example (MemberAdd) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints[:2], DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() peerURLs := endpoints[2:] mresp, err := cli.MemberAdd(context.Background(), peerURLs) if err != nil { log.Fatal(err) } fmt.Println("added member.PeerURLs:", mresp.Member.PeerURLs) // added member.PeerURLs: [http://localhost:32380]
Output:
Example (MemberLeader) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.MemberLeader(context.Background()) if err != nil { log.Fatal(err) } fmt.Println("leader:", resp.Name) // leader: infra1
Output:
Example (MemberList) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.MemberList(context.Background()) if err != nil { log.Fatal(err) } fmt.Println("members:", len(resp.Members)) // members: 3
Output:
Example (MemberRemove) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints[1:], DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.MemberList(context.Background()) if err != nil { log.Fatal(err) } _, err = cli.MemberRemove(context.Background(), resp.Members[0].ID) if err != nil { log.Fatal(err) }
Output:
Example (MemberUpdate) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.MemberList(context.Background()) if err != nil { log.Fatal(err) } peerURLs := []string{"http://localhost:12378"} _, err = cli.MemberUpdate(context.Background(), resp.Members[0].ID, peerURLs) if err != nil { log.Fatal(err) }
Output:
func NewCluster ¶
type CompareResult ¶
type CompareResult int
type CompareTarget ¶
type CompareTarget int
const ( CompareVersion CompareTarget = iota CompareCreated CompareModified CompareValue )
type Config ¶
type Config struct { // Endpoints is a list of URLs Endpoints []string // RetryDialer chooses the next endpoint to use RetryDialer EndpointDialer // DialTimeout is the timeout for failing to establish a connection. DialTimeout time.Duration // TLS holds the client secure credentials, if any. TLS *tls.Config }
type DefragmentResponse ¶
type DefragmentResponse pb.DefragmentResponse
type DeleteResponse ¶
type DeleteResponse pb.DeleteRangeResponse
type EndpointDialer ¶
type EndpointDialer func(*Client) (*grpc.ClientConn, error)
EndpointDialer is a policy for choosing which endpoint to dial next
type GetResponse ¶
type GetResponse pb.RangeResponse
type KV ¶
type KV interface { // Put puts a key-value pair into etcd. // Note that key,value can be plain bytes array and string is // an immutable representation of that bytes array. // To get a string of bytes, do string([]byte(0x10, 0x20)). Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error) // Get retrieves keys. // By default, Get will return the value for "key", if any. // When passed WithRange(end), Get will return the keys in the range [key, end). // When passed WithFromKey(), Get returns keys greater than or equal to key. // When passed WithRev(rev) with rev > 0, Get retrieves keys at the given revision; // if the required revision is compacted, the request will fail with ErrCompacted . // When passed WithLimit(limit), the number of returned keys is bounded by limit. // When passed WithSort(), the keys will be sorted. Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error) // Delete deletes a key, or optionally using WithRange(end), [key, end). Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error) // Compact compacts etcd KV history before the given rev. Compact(ctx context.Context, rev int64) error // Do applies a single Op on KV without a transaction. // Do is useful when creating arbitrary operations to be issued at a // later time; the user can range over the operations, calling Do to // execute them. Get/Put/Delete, on the other hand, are best suited // for when the operation should be issued at the time of declaration. Do(ctx context.Context, op Op) (OpResponse, error) // Txn creates a transaction. Txn(ctx context.Context) Txn }
Example (Compact) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := cli.Get(ctx, "foo") cancel() if err != nil { log.Fatal(err) } compRev := resp.Header.Revision // specify compact revision of your choice ctx, cancel = context.WithTimeout(context.Background(), requestTimeout) err = cli.Compact(ctx, compRev) cancel() if err != nil { log.Fatal(err) }
Output:
Example (Delete) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := cli.Delete(ctx, "key", clientv3.WithPrefix()) cancel() if err != nil { log.Fatal(err) } fmt.Println("Deleted", resp.Deleted, "keys") // Deleted n keys
Output:
Example (Do) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() ops := []clientv3.Op{ clientv3.OpPut("put-key", "123"), clientv3.OpGet("put-key"), clientv3.OpPut("put-key", "456")} for _, op := range ops { if _, err := cli.Do(context.TODO(), op); err != nil { log.Fatal(err) } }
Output:
Example (Get) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() _, err = cli.Put(context.TODO(), "foo", "bar") if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := cli.Get(ctx, "foo") cancel() if err != nil { log.Fatal(err) } for _, ev := range resp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } // foo : bar
Output:
Example (GetSortedPrefix) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() for i := range make([]int, 3) { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) _, err = cli.Put(ctx, fmt.Sprintf("key_%d", i), "value") cancel() if err != nil { log.Fatal(err) } } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := cli.Get(ctx, "key", clientv3.WithPrefix(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortDescend)) cancel() if err != nil { log.Fatal(err) } for _, ev := range resp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } // key_2 : value // key_1 : value // key_0 : value
Output:
Example (Put) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) resp, err := cli.Put(ctx, "sample_key", "sample_value") cancel() if err != nil { log.Fatal(err) } fmt.Println("current revision:", resp.Header.Revision) // revision start at 1 // current revision: 2
Output:
Example (Txn) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() kvc := clientv3.NewKV(cli) _, err = kvc.Put(context.TODO(), "key", "xyz") if err != nil { log.Fatal(err) } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) _, err = kvc.Txn(ctx). If(clientv3.Compare(clientv3.Value("key"), ">", "abc")). // txn value comparisons are lexical Then(clientv3.OpPut("key", "XYZ")). // this runs, since 'xyz' > 'abc' Else(clientv3.OpPut("key", "ABC")). Commit() cancel() if err != nil { log.Fatal(err) } gresp, err := kvc.Get(context.TODO(), "key") cancel() if err != nil { log.Fatal(err) } for _, ev := range gresp.Kvs { fmt.Printf("%s : %s\n", ev.Key, ev.Value) } // key : XYZ
Output:
type Lease ¶
type Lease interface { // Create creates a new lease. Create(ctx context.Context, ttl int64) (*LeaseCreateResponse, error) // Revoke revokes the given lease. Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) // KeepAlive keeps the given lease alive forever. KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error) // KeepAliveOnce renews the lease once. In most of the cases, Keepalive // should be used instead of KeepAliveOnce. KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error) // Close releases all resources Lease keeps for efficient communication // with the etcd server. Close() error }
Example (Create) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() // minimum lease TTL is 5-second resp, err := cli.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } // after 5 seconds, the key 'foo' will be removed _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) }
Output:
Example (KeepAlive) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // the key 'foo' will be kept forever _, err = cli.KeepAlive(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) }
Output:
Example (KeepAliveOnce) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // to renew the lease only once _, err = cli.KeepAliveOnce(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) }
Output:
Example (Revoke) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() resp, err := cli.Create(context.TODO(), 5) if err != nil { log.Fatal(err) } _, err = cli.Put(context.TODO(), "foo", "bar", clientv3.WithLease(clientv3.LeaseID(resp.ID))) if err != nil { log.Fatal(err) } // revoking lease expires the key attached to its lease ID _, err = cli.Revoke(context.TODO(), clientv3.LeaseID(resp.ID)) if err != nil { log.Fatal(err) } gresp, err := cli.Get(context.TODO(), "foo") if err != nil { log.Fatal(err) } fmt.Println("number of keys:", len(gresp.Kvs)) // number of keys: 0
Output:
type LeaseCreateResponse ¶
type LeaseCreateResponse pb.LeaseCreateResponse
type LeaseID ¶
type LeaseID int64
const ( // NoLease is a lease ID for the absence of a lease. NoLease LeaseID = 0 )
type LeaseKeepAliveResponse ¶
type LeaseKeepAliveResponse pb.LeaseKeepAliveResponse
type LeaseRevokeResponse ¶
type LeaseRevokeResponse pb.LeaseRevokeResponse
type Maintenance ¶
type Maintenance interface { // Defragment defragments storage backend of the etcd member with given endpoint. // Defragment is only needed when deleting a large number of keys and want to reclaim // the resources. // Defragment is an expensive operation. User should avoid defragmenting multiple members // at the same time. // To defragment multiple members in the cluster, user need to call defragment multiple // times with different endpoints. Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) }
type MemberAddResponse ¶
type MemberAddResponse pb.MemberAddResponse
type MemberListResponse ¶
type MemberListResponse pb.MemberListResponse
type MemberRemoveResponse ¶
type MemberRemoveResponse pb.MemberRemoveResponse
type MemberUpdateResponse ¶
type MemberUpdateResponse pb.MemberUpdateResponse
type Op ¶
type Op struct {
// contains filtered or unexported fields
}
Op represents an Operation that kv can execute.
type OpOption ¶
type OpOption func(*Op)
OpOption configures Operations like Get, Put, Delete.
func WithFirstCreate ¶
func WithFirstCreate() []OpOption
WithFirstCreate gets the key with the oldest creation revision in the request range.
func WithFirstKey ¶
func WithFirstKey() []OpOption
WithFirstKey gets the lexically first key in the request range.
func WithFirstRev ¶
func WithFirstRev() []OpOption
WithFirstRev gets the key with the oldest modification revision in the request range.
func WithFromKey ¶
func WithFromKey() OpOption
WithFromKey specifies the range of 'Get' or 'Delete' requests to be equal or greater than they key in the argument.
func WithLastCreate ¶
func WithLastCreate() []OpOption
WithLastCreate gets the key with the latest creation revision in the request range.
func WithLastKey ¶
func WithLastKey() []OpOption
WithLastKey gets the lexically last key in the request range.
func WithLastRev ¶
func WithLastRev() []OpOption
WithLastRev gets the key with the latest modification revision in the request range.
func WithPrefix ¶
func WithPrefix() OpOption
WithPrefix enables 'Get', 'Delete', or 'Watch' requests to operate on the keys with matching prefix. For example, 'Get(foo, WithPrefix())' can return 'foo1', 'foo2', and so on.
func WithProgressNotify ¶
func WithProgressNotify() OpOption
WithProgressNotify makes watch server send periodic progress updates. Progress updates have zero events in WatchResponse.
func WithRange ¶
WithRange specifies the range of 'Get' or 'Delete' requests. For example, 'Get' requests with 'WithRange(end)' returns the keys in the range [key, end).
func WithRev ¶
WithRev specifies the store revision for 'Get' request. Or the start revision of 'Watch' request.
func WithSerializable ¶
func WithSerializable() OpOption
WithSerializable makes 'Get' request serializable. By default, it's linearizable. Serializable requests are better for lower latency requirement.
func WithSort ¶
func WithSort(target SortTarget, order SortOrder) OpOption
WithSort specifies the ordering in 'Get' request. It requires 'WithRange' and/or 'WithPrefix' to be specified too. 'target' specifies the target to sort by: key, version, revisions, value. 'order' can be either 'SortNone', 'SortAscend', 'SortDescend'.
type OpResponse ¶
type OpResponse struct {
// contains filtered or unexported fields
}
type PutResponse ¶
type PutResponse pb.PutResponse
type SortOption ¶
type SortOption struct { Target SortTarget Order SortOrder }
type SortTarget ¶
type SortTarget int
const ( SortByKey SortTarget = iota SortByVersion SortByCreatedRev SortByModifiedRev SortByValue )
type Txn ¶
type Txn interface { // If takes a list of comparison. If all comparisons passed in succeed, // the operations passed into Then() will be executed. Or the operations // passed into Else() will be executed. If(cs ...Cmp) Txn // Then takes a list of operations. The Ops list will be executed, if the // comparisons passed in If() succeed. Then(ops ...Op) Txn // Else takes a list of operations. The Ops list will be executed, if the // comparisons passed in If() fail. Else(ops ...Op) Txn // Commit tries to commit the transaction. Commit() (*TxnResponse, error) }
Tx.If(
Compare(Value(k1), ">", v1), Compare(Version(k1), "=", 2)
).Then(
OpPut(k2,v2), OpPut(k3,v3)
).Else(
OpPut(k4,v4), OpPut(k5,v5)
).Commit()
type TxnResponse ¶
type TxnResponse pb.TxnResponse
type WatchChan ¶
type WatchChan <-chan WatchResponse
type WatchResponse ¶
type WatchResponse struct { Header pb.ResponseHeader Events []*storagepb.Event // CompactRevision is the minimum revision the watcher may receive. CompactRevision int64 // Canceled is used to indicate watch failure. // If the watch failed and the stream was about to close, before the channel is closed, // the channel sends a final response that has Canceled set to true with a non-nil Err(). Canceled bool }
func (*WatchResponse) Err ¶
func (wr *WatchResponse) Err() error
Err is the error value if this WatchResponse holds an error.
func (*WatchResponse) IsProgressNotify ¶
func (wr *WatchResponse) IsProgressNotify() bool
IsProgressNotify returns true if the WatchResponse is progress notification.
type Watcher ¶
type Watcher interface { // Watch watches on a key or prefix. The watched events will be returned // through the returned channel. // If the watch is slow or the required rev is compacted, the watch request // might be canceled from the server-side and the chan will be closed. // 'opts' can be: 'WithRev' and/or 'WitchPrefix'. Watch(ctx context.Context, key string, opts ...OpOption) WatchChan // Close closes the watcher and cancels all watch requests. Close() error }
Example (Watch) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() rch := cli.Watch(context.Background(), "foo") for wresp := range rch { for _, ev := range wresp.Events { fmt.Printf("%s %q : %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value) } } // PUT "foo" : "bar"
Output:
Example (WatchPrefix) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } defer cli.Close() rch := cli.Watch(context.Background(), "foo", clientv3.WithPrefix()) for wresp := range rch { for _, ev := range wresp.Events { fmt.Printf("%s %q : %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value) } } // PUT "foo1" : "bar"
Output:
Example (WatchProgressNotify) ¶
cli, err := clientv3.New(clientv3.Config{ Endpoints: endpoints, DialTimeout: dialTimeout, }) if err != nil { log.Fatal(err) } rch := cli.Watch(context.Background(), "foo", clientv3.WithProgressNotify()) wresp := <-rch fmt.Printf("wresp.Header.Revision: %d\n", wresp.Header.Revision) fmt.Println("wresp.IsProgressNotify:", wresp.IsProgressNotify()) // wresp.Header.Revision: 0 // wresp.IsProgressNotify: true
Output:
func NewWatcher ¶
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package integration implements tests built upon embedded etcd, and focuses on correctness of etcd client.
|
Package integration implements tests built upon embedded etcd, and focuses on correctness of etcd client. |