From 06d5cf2d52490249c4c6f5cb8a1296e1c3a30f69 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Wed, 5 Oct 2016 09:36:06 -0700 Subject: [PATCH] clientv3: fix race on watch initial revision The initial revision was being updated in the substream goroutine defer; this was racing with the resume path fetching the initial revision when the substream closes during resume. Instead, update the initial revision whenever the substream processes a new watch response. Since the substream cannot receive a watch response while it is resuming, the write to the initial revision is ordered to always happen after the resume read. Fixes #6586 --- clientv3/watch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clientv3/watch.go b/clientv3/watch.go index e49dc82b541..81406c2f00a 100644 --- a/clientv3/watch.go +++ b/clientv3/watch.go @@ -573,7 +573,6 @@ func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{ if !resuming { ws.closing = true } - ws.initReq.rev = nextRev close(ws.donec) if !resuming { w.closingc <- ws @@ -619,6 +618,7 @@ func (w *watchGrpcStream) serveSubstream(ws *watcherStream, resumec chan struct{ if len(wr.Events) > 0 { nextRev = wr.Events[len(wr.Events)-1].Kv.ModRevision + 1 } + ws.initReq.rev = nextRev case <-ws.initReq.ctx.Done(): return case <-resumec: