Example #1
1
// snapshot reads all of a watcher; returns compaction revision if incomplete
// TODO: stabilize snapshot format
func snapshot(w io.Writer, c *clientv3.Client, rev int64) int64 {
	s := sync.NewSyncer(c, "", rev)

	rc, errc := s.SyncBase(context.TODO())

	for r := range rc {
		for _, kv := range r.Kvs {
			fmt.Fprintln(w, kv)
		}
	}

	err := <-errc
	if err != nil {
		if err == v3rpc.ErrCompacted {
			// will get correct compact revision on retry
			return rev + 1
		}
		// failed for some unknown reason, retry on same revision
		return rev
	}

	wc := s.SyncUpdates(context.TODO())

	for wr := range wc {
		if len(wr.Events) == 0 {
			return wr.CompactRevision
		}
		for _, ev := range wr.Events {
			fmt.Fprintln(w, ev)
		}
		rev := wr.Events[len(wr.Events)-1].Kv.ModRevision
		if rev >= wr.Header.Revision {
			break
		}
	}

	return 0
}
Example #2
0
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
}