client.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Copyright 2016 CoreOS, Inc.
  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. "errors"
  17. "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
  18. pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
  19. spb "github.com/coreos/etcd/storage/storagepb"
  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. )
  26. // deleteRevKey deletes a key by revision, returning false if key is missing
  27. func deleteRevKey(kvc pb.KVClient, key string, rev int64) (bool, error) {
  28. cmp := &pb.Compare{
  29. Result: pb.Compare_EQUAL,
  30. Target: pb.Compare_MOD,
  31. Key: []byte(key),
  32. TargetUnion: &pb.Compare_ModRevision{ModRevision: rev},
  33. }
  34. req := &pb.RequestUnion{Request: &pb.RequestUnion_RequestDeleteRange{
  35. RequestDeleteRange: &pb.DeleteRangeRequest{Key: []byte(key)}}}
  36. txnresp, err := kvc.Txn(
  37. context.TODO(),
  38. &pb.TxnRequest{
  39. Compare: []*pb.Compare{cmp},
  40. Success: []*pb.RequestUnion{req},
  41. Failure: nil,
  42. })
  43. if err != nil {
  44. return false, err
  45. } else if txnresp.Succeeded == false {
  46. return false, nil
  47. }
  48. return true, nil
  49. }
  50. func claimFirstKey(kvc pb.KVClient, kvs []*spb.KeyValue) (*spb.KeyValue, error) {
  51. for _, kv := range kvs {
  52. ok, err := deleteRevKey(kvc, string(kv.Key), kv.ModRevision)
  53. if err != nil {
  54. return nil, err
  55. } else if ok {
  56. return kv, nil
  57. }
  58. }
  59. return nil, nil
  60. }
  61. func putEmptyKey(kv pb.KVClient, key string) (*pb.PutResponse, error) {
  62. return kv.Put(context.TODO(), &pb.PutRequest{Key: []byte(key), Value: []byte{}})
  63. }
  64. // deletePrefix performs a RangeRequest to get keys on a given prefix
  65. func deletePrefix(kv pb.KVClient, prefix string) (*pb.DeleteRangeResponse, error) {
  66. return kv.DeleteRange(
  67. context.TODO(),
  68. &pb.DeleteRangeRequest{
  69. Key: []byte(prefix),
  70. RangeEnd: []byte(prefixEnd(prefix))})
  71. }