...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package recipe
16
17 import (
18 "context"
19 "errors"
20
21 spb "go.etcd.io/etcd/api/v3/mvccpb"
22 v3 "go.etcd.io/etcd/client/v3"
23 )
24
25 var (
26 ErrKeyExists = errors.New("key already exists")
27 ErrWaitMismatch = errors.New("unexpected wait result")
28 ErrTooManyClients = errors.New("too many clients")
29 ErrNoWatcher = errors.New("no watcher channel")
30 )
31
32
33 func deleteRevKey(kv v3.KV, key string, rev int64) (bool, error) {
34 cmp := v3.Compare(v3.ModRevision(key), "=", rev)
35 req := v3.OpDelete(key)
36 txnresp, err := kv.Txn(context.TODO()).If(cmp).Then(req).Commit()
37 if err != nil {
38 return false, err
39 } else if !txnresp.Succeeded {
40 return false, nil
41 }
42 return true, nil
43 }
44
45 func claimFirstKey(kv v3.KV, kvs []*spb.KeyValue) (*spb.KeyValue, error) {
46 for _, k := range kvs {
47 ok, err := deleteRevKey(kv, string(k.Key), k.ModRevision)
48 if err != nil {
49 return nil, err
50 } else if ok {
51 return k, nil
52 }
53 }
54 return nil, nil
55 }
56
View as plain text