mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
clientv3: add send created notification
This commit is contained in:
parent
a60387bab2
commit
33c3583b50
@ -709,3 +709,21 @@ func TestWatchWithFilter(t *testing.T) {
|
|||||||
case <-time.After(100 * time.Millisecond):
|
case <-time.After(100 * time.Millisecond):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestWatchWithCreatedNotification checks that createdNotification works.
|
||||||
|
func TestWatchWithCreatedNotification(t *testing.T) {
|
||||||
|
cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
|
||||||
|
defer cluster.Terminate(t)
|
||||||
|
|
||||||
|
client := cluster.RandClient()
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
createC := client.Watch(ctx, "a", clientv3.WithCreatedNotify())
|
||||||
|
|
||||||
|
resp := <-createC
|
||||||
|
|
||||||
|
if !resp.Created {
|
||||||
|
t.Fatalf("expected created event, got %v", resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -50,6 +50,8 @@ type Op struct {
|
|||||||
|
|
||||||
// progressNotify is for progress updates.
|
// progressNotify is for progress updates.
|
||||||
progressNotify bool
|
progressNotify bool
|
||||||
|
// createdNotify is for created event
|
||||||
|
createdNotify bool
|
||||||
// filters for watchers
|
// filters for watchers
|
||||||
filterPut bool
|
filterPut bool
|
||||||
filterDelete bool
|
filterDelete bool
|
||||||
@ -116,6 +118,8 @@ func OpDelete(key string, opts ...OpOption) Op {
|
|||||||
panic("unexpected countOnly in delete")
|
panic("unexpected countOnly in delete")
|
||||||
case ret.filterDelete, ret.filterPut:
|
case ret.filterDelete, ret.filterPut:
|
||||||
panic("unexpected filter in delete")
|
panic("unexpected filter in delete")
|
||||||
|
case ret.createdNotify:
|
||||||
|
panic("unexpected createdNotify in delete")
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@ -138,6 +142,8 @@ func OpPut(key, val string, opts ...OpOption) Op {
|
|||||||
panic("unexpected countOnly in put")
|
panic("unexpected countOnly in put")
|
||||||
case ret.filterDelete, ret.filterPut:
|
case ret.filterDelete, ret.filterPut:
|
||||||
panic("unexpected filter in put")
|
panic("unexpected filter in put")
|
||||||
|
case ret.createdNotify:
|
||||||
|
panic("unexpected createdNotify in put")
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@ -281,6 +287,13 @@ func WithProgressNotify() OpOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithCreatedNotify makes watch server sends the created event.
|
||||||
|
func WithCreatedNotify() OpOption {
|
||||||
|
return func(op *Op) {
|
||||||
|
op.createdNotify = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithFilterPut discards PUT events from the watcher.
|
// WithFilterPut discards PUT events from the watcher.
|
||||||
func WithFilterPut() OpOption {
|
func WithFilterPut() OpOption {
|
||||||
return func(op *Op) { op.filterPut = true }
|
return func(op *Op) { op.filterPut = true }
|
||||||
|
@ -61,6 +61,9 @@ type WatchResponse struct {
|
|||||||
// the channel sends a final response that has Canceled set to true with a non-nil Err().
|
// the channel sends a final response that has Canceled set to true with a non-nil Err().
|
||||||
Canceled bool
|
Canceled bool
|
||||||
|
|
||||||
|
// Created is used to indicate the creation of the watcher.
|
||||||
|
Created bool
|
||||||
|
|
||||||
closeErr error
|
closeErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +101,7 @@ type watcher struct {
|
|||||||
|
|
||||||
// mu protects the grpc streams map
|
// mu protects the grpc streams map
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
// streams holds all the active grpc streams keyed by ctx value.
|
// streams holds all the active grpc streams keyed by ctx value.
|
||||||
streams map[string]*watchGrpcStream
|
streams map[string]*watchGrpcStream
|
||||||
}
|
}
|
||||||
@ -138,6 +142,8 @@ type watchRequest struct {
|
|||||||
key string
|
key string
|
||||||
end string
|
end string
|
||||||
rev int64
|
rev int64
|
||||||
|
// send created notification event if this field is true
|
||||||
|
createdNotify bool
|
||||||
// progressNotify is for progress updates
|
// progressNotify is for progress updates
|
||||||
progressNotify bool
|
progressNotify bool
|
||||||
// filters is the list of events to filter out
|
// filters is the list of events to filter out
|
||||||
@ -223,6 +229,7 @@ func (w *watcher) Watch(ctx context.Context, key string, opts ...OpOption) Watch
|
|||||||
|
|
||||||
wr := &watchRequest{
|
wr := &watchRequest{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
createdNotify: ow.createdNotify,
|
||||||
key: string(ow.key),
|
key: string(ow.key),
|
||||||
end: string(ow.end),
|
end: string(ow.end),
|
||||||
rev: ow.rev,
|
rev: ow.rev,
|
||||||
@ -418,6 +425,7 @@ func (w *watchGrpcStream) run() {
|
|||||||
w.addStream(pbresp, pendingReq)
|
w.addStream(pbresp, pendingReq)
|
||||||
pendingReq = nil
|
pendingReq = nil
|
||||||
curReqC = w.reqc
|
curReqC = w.reqc
|
||||||
|
w.dispatchEvent(pbresp)
|
||||||
case pbresp.Canceled:
|
case pbresp.Canceled:
|
||||||
delete(cancelSet, pbresp.WatchId)
|
delete(cancelSet, pbresp.WatchId)
|
||||||
// shutdown serveStream, if any
|
// shutdown serveStream, if any
|
||||||
@ -489,19 +497,23 @@ func (w *watchGrpcStream) dispatchEvent(pbresp *pb.WatchResponse) bool {
|
|||||||
w.mu.RLock()
|
w.mu.RLock()
|
||||||
defer w.mu.RUnlock()
|
defer w.mu.RUnlock()
|
||||||
ws, ok := w.streams[pbresp.WatchId]
|
ws, ok := w.streams[pbresp.WatchId]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
events := make([]*Event, len(pbresp.Events))
|
events := make([]*Event, len(pbresp.Events))
|
||||||
for i, ev := range pbresp.Events {
|
for i, ev := range pbresp.Events {
|
||||||
events[i] = (*Event)(ev)
|
events[i] = (*Event)(ev)
|
||||||
}
|
}
|
||||||
if ok {
|
wr := &WatchResponse{
|
||||||
wr := &WatchResponse{
|
Header: *pbresp.Header,
|
||||||
Header: *pbresp.Header,
|
Events: events,
|
||||||
Events: events,
|
CompactRevision: pbresp.CompactRevision,
|
||||||
CompactRevision: pbresp.CompactRevision,
|
Created: pbresp.Created,
|
||||||
Canceled: pbresp.Canceled}
|
Canceled: pbresp.Canceled,
|
||||||
ws.recvc <- wr
|
|
||||||
}
|
}
|
||||||
return ok
|
ws.recvc <- wr
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// serveWatchClient forwards messages from the grpc stream to run()
|
// serveWatchClient forwards messages from the grpc stream to run()
|
||||||
@ -533,6 +545,14 @@ func (w *watchGrpcStream) serveStream(ws *watcherStream) {
|
|||||||
for !closing {
|
for !closing {
|
||||||
curWr := emptyWr
|
curWr := emptyWr
|
||||||
outc := ws.outc
|
outc := ws.outc
|
||||||
|
|
||||||
|
// ignore created event if create notify is not requested or
|
||||||
|
// we already sent the initial created event (when we are on the resume path).
|
||||||
|
if len(wrs) > 0 && wrs[0].Created &&
|
||||||
|
(!ws.initReq.createdNotify || ws.lastRev != 0) {
|
||||||
|
wrs = wrs[1:]
|
||||||
|
}
|
||||||
|
|
||||||
if len(wrs) > 0 {
|
if len(wrs) > 0 {
|
||||||
curWr = wrs[0]
|
curWr = wrs[0]
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user