grpcproxy: fix more issues in watch path

This commit is contained in:
Xiang Li 2016-09-02 14:22:06 -07:00
parent f7293125cf
commit 8cd47c4348
3 changed files with 29 additions and 3 deletions

View File

@ -42,12 +42,16 @@ func (w *watcher) send(wr clientv3.WatchResponse) {
events := make([]*mvccpb.Event, 0, len(wr.Events)) events := make([]*mvccpb.Event, 0, len(wr.Events))
var lastRev int64
for i := range wr.Events { for i := range wr.Events {
ev := (*mvccpb.Event)(wr.Events[i]) ev := (*mvccpb.Event)(wr.Events[i])
if ev.Kv.ModRevision <= w.rev { if ev.Kv.ModRevision <= w.rev {
continue continue
} else { } else {
w.rev = ev.Kv.ModRevision // We cannot update w.rev here.
// txn can have multiple events with the same rev.
// If we update w.rev here, we would skip some events in the same txn.
lastRev = ev.Kv.ModRevision
} }
filtered := false filtered := false
@ -65,6 +69,10 @@ func (w *watcher) send(wr clientv3.WatchResponse) {
} }
} }
if lastRev > w.rev {
w.rev = lastRev
}
// all events are filtered out? // all events are filtered out?
if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 { if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 {
return return

View File

@ -67,10 +67,13 @@ func (wg *watcherGroup) broadcast(wr clientv3.WatchResponse) {
} }
} }
func (wg *watcherGroup) add(rid receiverID, w watcher) { // add adds the watcher into the group with given ID.
// The current revision of the watcherGroup is returned.
func (wg *watcherGroup) add(rid receiverID, w watcher) int64 {
wg.mu.Lock() wg.mu.Lock()
defer wg.mu.Unlock() defer wg.mu.Unlock()
wg.receivers[rid] = w wg.receivers[rid] = w
return wg.rev
} }
func (wg *watcherGroup) delete(rid receiverID) { func (wg *watcherGroup) delete(rid receiverID) {

View File

@ -18,6 +18,8 @@ import (
"sync" "sync"
"github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -38,8 +40,21 @@ func (wgs *watchergroups) addWatcher(rid receiverID, w watcher) {
groups := wgs.groups groups := wgs.groups
if wg, ok := groups[w.wr]; ok { if wg, ok := groups[w.wr]; ok {
wg.add(rid, w) rev := wg.add(rid, w)
wgs.idToGroup[rid] = wg wgs.idToGroup[rid] = wg
resp := &pb.WatchResponse{
Header: &pb.ResponseHeader{
// todo: fill in ClusterId
// todo: fill in MemberId:
Revision: rev,
// todo: fill in RaftTerm:
},
WatchId: rid.watcherID,
Created: true,
}
w.ch <- resp
return return
} }