func makeMirror(ctx context.Context, c *clientv3.Client, dc *clientv3.Client) error { total := int64(0) go func() { for { time.Sleep(30 * time.Second) fmt.Println(atomic.LoadInt64(&total)) } }() // TODO: remove the prefix of the destination cluster? s := mirror.NewSyncer(c, mmprefix, 0) rc, errc := s.SyncBase(ctx) for r := range rc { for _, kv := range r.Kvs { _, err := dc.Put(ctx, string(kv.Key), string(kv.Value)) if err != nil { return err } atomic.AddInt64(&total, 1) } } err := <-errc if err != nil { return err } wc := s.SyncUpdates(ctx) for wr := range wc { if wr.CompactRevision != 0 { return rpctypes.ErrCompacted } var rev int64 ops := []clientv3.Op{} for _, ev := range wr.Events { nrev := ev.Kv.ModRevision if rev != 0 && nrev > rev { _, err := dc.Txn(ctx).Then(ops...).Commit() if err != nil { return err } ops = []clientv3.Op{} } switch ev.Type { case storagepb.PUT: ops = append(ops, clientv3.OpPut(string(ev.Kv.Key), string(ev.Kv.Value))) atomic.AddInt64(&total, 1) case storagepb.DELETE, storagepb.EXPIRE: ops = append(ops, clientv3.OpDelete(string(ev.Kv.Key))) atomic.AddInt64(&total, 1) default: panic("unexpected event type") } } if len(ops) != 0 { _, err := dc.Txn(ctx).Then(ops...).Commit() if err != nil { return err } } } return nil }
func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.Object, v reflect.Value, precondtions *storage.Preconditions) error { getResp, err := s.client.KV.Get(ctx, key) if err != nil { return err } for { origState, err := s.getState(getResp, key, v, false) if err != nil { return err } if err := checkPreconditions(key, precondtions, origState.obj); err != nil { return err } txnResp, err := s.client.KV.Txn(ctx).If( clientv3.Compare(clientv3.ModRevision(key), "=", origState.rev), ).Then( clientv3.OpDelete(key), ).Else( clientv3.OpGet(key), ).Commit() if err != nil { return err } if !txnResp.Succeeded { getResp = (*clientv3.GetResponse)(txnResp.Responses[0].GetResponseRange()) glog.V(4).Infof("deletion of %s failed because of a conflict, going to retry", key) continue } return decode(s.codec, s.versioner, origState.data, out, origState.rev) } }
func parseRequestUnion(line string) (*clientv3.Op, error) { args := argify(line) if len(args) < 2 { return nil, fmt.Errorf("invalid txn compare request: %s", line) } opc := make(chan clientv3.Op, 1) put := NewPutCommand() put.Run = func(cmd *cobra.Command, args []string) { key, value, opts := getPutOp(cmd, args) opc <- clientv3.OpPut(key, value, opts...) } get := NewGetCommand() get.Run = func(cmd *cobra.Command, args []string) { key, opts := getGetOp(cmd, args) opc <- clientv3.OpGet(key, opts...) } del := NewDelCommand() del.Run = func(cmd *cobra.Command, args []string) { key, opts := getDelOp(cmd, args) opc <- clientv3.OpDelete(key, opts...) } cmds := &cobra.Command{SilenceErrors: true} cmds.AddCommand(put, get, del) cmds.SetArgs(args) if err := cmds.Execute(); err != nil { return nil, fmt.Errorf("invalid txn request: %s", line) } op := <-opc return &op, nil }
// TestGRPCResolverMultiInit ensures the resolver will initialize // correctly with multiple hosts and correctly receive multiple // updates in a single revision. func TestGRPCResolverMulti(t *testing.T) { defer testutil.AfterTest(t) clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1}) defer clus.Terminate(t) c := clus.RandClient() v, verr := json.Marshal(naming.Update{Addr: "127.0.0.1", Metadata: "md"}) if verr != nil { t.Fatal(verr) } if _, err := c.Put(context.TODO(), "foo/host", string(v)); err != nil { t.Fatal(err) } if _, err := c.Put(context.TODO(), "foo/host2", string(v)); err != nil { t.Fatal(err) } r := GRPCResolver{c} w, err := r.Resolve("foo") if err != nil { t.Fatal("failed to resolve foo", err) } defer w.Close() updates, nerr := w.Next() if nerr != nil { t.Fatal(nerr) } if len(updates) != 2 { t.Fatalf("expected two updates, got %+v", updates) } _, err = c.Txn(context.TODO()).Then(etcd.OpDelete("foo/host"), etcd.OpDelete("foo/host2")).Commit() if err != nil { t.Fatal(err) } updates, nerr = w.Next() if nerr != nil { t.Fatal(nerr) } if len(updates) != 2 || (updates[0].Op != naming.Delete && updates[1].Op != naming.Delete) { t.Fatalf("expected two updates, got %+v", updates) } }
func DelRequestToOp(r *pb.DeleteRangeRequest) clientv3.Op { opts := []clientv3.OpOption{} if len(r.RangeEnd) != 0 { opts = append(opts, clientv3.WithRange(string(r.RangeEnd))) } return clientv3.OpDelete(string(r.Key), opts...) }
func (b *blockEtcd) DeleteVolume() error { vid := uint64(b.vid) tx := b.Etcd.Client.Txn(b.getContext()).If( etcdv3.Compare(etcdv3.Version(etcd.MkKey("volumemeta", etcd.Uint64ToHex(vid), "blocklock")), "=", 0), ).Then( etcdv3.OpDelete(etcd.MkKey("volumes", b.name)), etcdv3.OpDelete(etcd.MkKey("volumeid", etcd.Uint64ToHex(vid))), etcdv3.OpDelete(etcd.MkKey("volumemeta", etcd.Uint64ToHex(vid)), etcdv3.WithPrefix()), ) resp, err := tx.Commit() if err != nil { return err } if !resp.Succeeded { return torus.ErrLocked } return nil }
// deleteRevKey deletes a key by revision, returning false if key is missing func deleteRevKey(kv v3.KV, key string, rev int64) (bool, error) { cmp := v3.Compare(v3.ModRevision(key), "=", rev) req := v3.OpDelete(key) txnresp, err := kv.Txn(context.TODO()).If(cmp).Then(req).Commit() if err != nil { return false, err } else if !txnresp.Succeeded { return false, nil } return true, nil }
func (b *blockEtcd) DeleteSnapshot(name string) error { vid := uint64(b.vid) k := etcd.MkKey("volumemeta", etcd.Uint64ToHex(vid), "snapshots", name) tx := b.Etcd.Client.Txn(b.getContext()).If( etcdv3.Compare(etcdv3.Version(k), ">", 0), ).Then( etcdv3.OpDelete(k), ) resp, err := tx.Commit() if err != nil { return err } if !resp.Succeeded { return torus.ErrLocked } return nil }
func (s *store) unconditionalDelete(ctx context.Context, key string, out runtime.Object) error { // We need to do get and delete in single transaction in order to // know the value and revision before deleting it. txnResp, err := s.client.KV.Txn(ctx).If().Then( clientv3.OpGet(key), clientv3.OpDelete(key), ).Commit() if err != nil { return err } getResp := txnResp.Responses[0].GetResponseRange() if len(getResp.Kvs) == 0 { return storage.NewKeyNotFoundError(key, 0) } kv := getResp.Kvs[0] return decode(s.codec, s.versioner, kv.Value, out, kv.ModRevision) }
func (b *blockEtcd) Unlock() error { vid := uint64(b.vid) k := etcd.MkKey("volumemeta", etcd.Uint64ToHex(vid), "blocklock") tx := b.Etcd.Client.Txn(b.getContext()).If( etcdv3.Compare(etcdv3.Version(k), ">", 0), etcdv3.Compare(etcdv3.Value(k), "=", b.Etcd.UUID()), ).Then( etcdv3.OpDelete(etcd.MkKey("volumemeta", etcd.Uint64ToHex(vid), "blocklock")), ) resp, err := tx.Commit() if err != nil { return err } if !resp.Succeeded { return torus.ErrLocked } return nil }
func makeMirror(ctx context.Context, c *clientv3.Client, dc *clientv3.Client) error { total := int64(0) go func() { for { time.Sleep(30 * time.Second) fmt.Println(atomic.LoadInt64(&total)) } }() s := mirror.NewSyncer(c, mmprefix, 0) rc, errc := s.SyncBase(ctx) // if destination prefix is specified and remove destination prefix is true return error if mmnodestprefix && len(mmdestprefix) > 0 { ExitWithError(ExitBadArgs, fmt.Errorf("`--dest-prefix` and `--no-dest-prefix` cannot be set at the same time, choose one.")) } // if remove destination prefix is false and destination prefix is empty set the value of destination prefix same as prefix if !mmnodestprefix && len(mmdestprefix) == 0 { mmdestprefix = mmprefix } for r := range rc { for _, kv := range r.Kvs { _, err := dc.Put(ctx, modifyPrefix(string(kv.Key)), string(kv.Value)) if err != nil { return err } atomic.AddInt64(&total, 1) } } err := <-errc if err != nil { return err } wc := s.SyncUpdates(ctx) for wr := range wc { if wr.CompactRevision != 0 { return rpctypes.ErrCompacted } var rev int64 ops := []clientv3.Op{} for _, ev := range wr.Events { nrev := ev.Kv.ModRevision if rev != 0 && nrev > rev { _, err := dc.Txn(ctx).Then(ops...).Commit() if err != nil { return err } ops = []clientv3.Op{} } switch ev.Type { case mvccpb.PUT: ops = append(ops, clientv3.OpPut(modifyPrefix(string(ev.Kv.Key)), string(ev.Kv.Value))) atomic.AddInt64(&total, 1) case mvccpb.DELETE: ops = append(ops, clientv3.OpDelete(modifyPrefix(string(ev.Kv.Key)))) atomic.AddInt64(&total, 1) default: panic("unexpected event type") } } if len(ops) != 0 { _, err := dc.Txn(ctx).Then(ops...).Commit() if err != nil { return err } } } return nil }
func (s *stm) Del(key string) { s.wset[key] = stmPut{"", v3.OpDelete(key)} }
func makeMirror(ctx context.Context, c *clientv3.Client, dc *clientv3.Client) error { // TODO: remove the prefix of the destination cluster? dkv := clientv3.NewKV(dc) s := sync.NewSyncer(c, mmprefix, 0) rc, errc := s.SyncBase(ctx) for r := range rc { for _, kv := range r.Kvs { _, err := dkv.Put(ctx, string(kv.Key), string(kv.Value)) if err != nil { return err } } } err := <-errc if err != nil { return err } wc := s.SyncUpdates(ctx) for wr := range wc { if wr.CompactRevision != 0 { return v3rpc.ErrCompacted } var rev int64 ops := []clientv3.Op{} for _, ev := range wr.Events { nrev := ev.Kv.ModRevision if rev != 0 && nrev > rev { _, err := dkv.Txn(ctx).Then(ops...).Commit() if err != nil { return err } ops = []clientv3.Op{} } switch ev.Type { case storagepb.PUT: ops = append(ops, clientv3.OpPut(string(ev.Kv.Key), string(ev.Kv.Value))) case storagepb.DELETE, storagepb.EXPIRE: ops = append(ops, clientv3.OpDelete(string(ev.Kv.Key))) default: panic("unexpected event type") } } if len(ops) != 0 { _, err := dkv.Txn(ctx).Then(ops...).Commit() if err != nil { return err } } } return nil }