Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 1 | // Copyright 2016 The etcd Authors |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | // Package clientv3 implements the official Go etcd client for v3. |
| 16 | // |
| 17 | // Create client using `clientv3.New`: |
| 18 | // |
| 19 | // // expect dial time-out on ipv4 blackhole |
| 20 | // _, err := clientv3.New(clientv3.Config{ |
| 21 | // Endpoints: []string{"http://254.0.0.1:12345"}, |
khenaidoo | 2672188 | 2021-08-11 17:42:52 -0400 | [diff] [blame^] | 22 | // DialTimeout: 2 * time.Second |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 23 | // }) |
| 24 | // |
| 25 | // // etcd clientv3 >= v3.2.10, grpc/grpc-go >= v1.7.3 |
| 26 | // if err == context.DeadlineExceeded { |
| 27 | // // handle errors |
| 28 | // } |
| 29 | // |
| 30 | // // etcd clientv3 <= v3.2.9, grpc/grpc-go <= v1.2.1 |
| 31 | // if err == grpc.ErrClientConnTimeout { |
| 32 | // // handle errors |
| 33 | // } |
| 34 | // |
| 35 | // cli, err := clientv3.New(clientv3.Config{ |
| 36 | // Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}, |
| 37 | // DialTimeout: 5 * time.Second, |
| 38 | // }) |
| 39 | // if err != nil { |
| 40 | // // handle error! |
| 41 | // } |
| 42 | // defer cli.Close() |
| 43 | // |
| 44 | // Make sure to close the client after using it. If the client is not closed, the |
| 45 | // connection will have leaky goroutines. |
| 46 | // |
| 47 | // To specify a client request timeout, wrap the context with context.WithTimeout: |
| 48 | // |
| 49 | // ctx, cancel := context.WithTimeout(context.Background(), timeout) |
| 50 | // resp, err := kvc.Put(ctx, "sample_key", "sample_value") |
| 51 | // cancel() |
| 52 | // if err != nil { |
| 53 | // // handle error! |
| 54 | // } |
| 55 | // // use the response |
| 56 | // |
| 57 | // The Client has internal state (watchers and leases), so Clients should be reused instead of created as needed. |
| 58 | // Clients are safe for concurrent use by multiple goroutines. |
| 59 | // |
| 60 | // etcd client returns 3 types of errors: |
| 61 | // |
| 62 | // 1. context error: canceled or deadline exceeded. |
| 63 | // 2. gRPC status error: e.g. when clock drifts in server-side before client's context deadline exceeded. |
khenaidoo | 2672188 | 2021-08-11 17:42:52 -0400 | [diff] [blame^] | 64 | // 3. gRPC error: see https://github.com/coreos/etcd/blob/master/etcdserver/api/v3rpc/rpctypes/error.go |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 65 | // |
| 66 | // Here is the example code to handle client errors: |
| 67 | // |
| 68 | // resp, err := kvc.Put(ctx, "", "") |
| 69 | // if err != nil { |
| 70 | // if err == context.Canceled { |
| 71 | // // ctx is canceled by another routine |
| 72 | // } else if err == context.DeadlineExceeded { |
| 73 | // // ctx is attached with a deadline and it exceeded |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 74 | // } else if ev, ok := status.FromError(err); ok { |
| 75 | // code := ev.Code() |
| 76 | // if code == codes.DeadlineExceeded { |
| 77 | // // server-side context might have timed-out first (due to clock skew) |
| 78 | // // while original client-side context is not timed-out yet |
| 79 | // } |
khenaidoo | 2672188 | 2021-08-11 17:42:52 -0400 | [diff] [blame^] | 80 | // } else if verr, ok := err.(*v3rpc.ErrEmptyKey); ok { |
| 81 | // // process (verr.Errors) |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 82 | // } else { |
| 83 | // // bad cluster endpoints, which are not etcd servers |
| 84 | // } |
| 85 | // } |
| 86 | // |
| 87 | // go func() { cli.Close() }() |
| 88 | // _, err := kvc.Get(ctx, "a") |
| 89 | // if err != nil { |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 90 | // if err == context.Canceled { |
| 91 | // // grpc balancer calls 'Get' with an inflight client.Close |
khenaidoo | 2672188 | 2021-08-11 17:42:52 -0400 | [diff] [blame^] | 92 | // } else if err == grpc.ErrClientConnClosing { |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 93 | // // grpc balancer calls 'Get' after client.Close. |
| 94 | // } |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 95 | // } |
| 96 | // |
Scott Baker | 2c1c482 | 2019-10-16 11:02:41 -0700 | [diff] [blame] | 97 | package clientv3 |