client.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  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. package recipe
  15. import (
  16. "context"
  17. "errors"
  18. v3 "go.etcd.io/etcd/clientv3"
  19. spb "go.etcd.io/etcd/mvcc/mvccpb"
  20. )
  21. var (
  22. ErrKeyExists = errors.New("key already exists")
  23. ErrWaitMismatch = errors.New("unexpected wait result")
  24. ErrTooManyClients = errors.New("too many clients")
  25. ErrNoWatcher = errors.New("no watcher channel")
  26. )
  27. // deleteRevKey deletes a key by revision, returning false if key is missing
  28. func deleteRevKey(kv v3.KV, key string, rev int64) (bool, error) {
  29. cmp := v3.Compare(v3.ModRevision(key), "=", rev)
  30. req := v3.OpDelete(key)
  31. txnresp, err := kv.Txn(context.TODO()).If(cmp).Then(req).Commit()
  32. if err != nil {
  33. return false, err
  34. } else if !txnresp.Succeeded {
  35. return false, nil
  36. }
  37. return true, nil
  38. }
  39. func claimFirstKey(kv v3.KV, kvs []*spb.KeyValue) (*spb.KeyValue, error) {
  40. for _, k := range kvs {
  41. ok, err := deleteRevKey(kv, string(k.Key), k.ModRevision)
  42. if err != nil {
  43. return nil, err
  44. } else if ok {
  45. return k, nil
  46. }
  47. }
  48. return nil, nil
  49. }