mirror of
https://github.com/nats-io/nats.go.git
synced 2025-09-26 20:41:41 +08:00
[FIXED] Ensure object watcher stop closes the updates channel (#1844)
Signed-off-by: Piotr Piotrowski <piotr@synadia.com>
This commit is contained in:
@@ -1330,6 +1330,9 @@ func (obs *obs) Watch(ctx context.Context, opts ...WatchOpt) (ObjectWatcher, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
sub.SetClosedHandler(func(_ string) {
|
||||||
|
close(w.updates)
|
||||||
|
})
|
||||||
w.sub = sub
|
w.sub = sub
|
||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
@@ -614,6 +614,37 @@ func TestKeyValueWatch(t *testing.T) {
|
|||||||
expectOk(t, kv.Delete(ctx, "age"))
|
expectOk(t, kv.Delete(ctx, "age"))
|
||||||
expectDelete("age", 6)
|
expectDelete("age", 6)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("stop watcher should not block", func(t *testing.T) {
|
||||||
|
s := RunBasicJetStreamServer()
|
||||||
|
defer shutdownJSServerAndRemoveStorage(t, s)
|
||||||
|
|
||||||
|
nc, js := jsClient(t, s)
|
||||||
|
defer nc.Close()
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
kv, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: "WATCH"})
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
watcher, err := kv.WatchAll(ctx)
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
expectInitDone := expectInitDoneF(t, watcher)
|
||||||
|
expectInitDone()
|
||||||
|
|
||||||
|
err = watcher.Stop()
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case _, ok := <-watcher.Updates():
|
||||||
|
if ok {
|
||||||
|
t.Fatalf("Expected channel to be closed")
|
||||||
|
}
|
||||||
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueWatchContext(t *testing.T) {
|
func TestKeyValueWatchContext(t *testing.T) {
|
||||||
|
@@ -695,6 +695,36 @@ func TestObjectWatch(t *testing.T) {
|
|||||||
expectOk(t, err)
|
expectOk(t, err)
|
||||||
expectUpdate("C")
|
expectUpdate("C")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("stop watcher should close the channel", func(t *testing.T) {
|
||||||
|
s := RunBasicJetStreamServer()
|
||||||
|
defer shutdownJSServerAndRemoveStorage(t, s)
|
||||||
|
|
||||||
|
nc, js := jsClient(t, s)
|
||||||
|
defer nc.Close()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
obs, err := js.CreateObjectStore(ctx, jetstream.ObjectStoreConfig{Bucket: "WATCH-TEST"})
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
watcher, err := obs.Watch(ctx)
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
expectInitDone := expectInitDoneF(t, watcher)
|
||||||
|
expectInitDone()
|
||||||
|
|
||||||
|
err = watcher.Stop()
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case _, ok := <-watcher.Updates():
|
||||||
|
if ok {
|
||||||
|
t.Fatalf("Expected channel to be closed")
|
||||||
|
}
|
||||||
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectLinks(t *testing.T) {
|
func TestObjectLinks(t *testing.T) {
|
||||||
|
@@ -1127,6 +1127,10 @@ func (obs *obs) Watch(opts ...WatchOpt) (ObjectWatcher, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// Set us up to close when the waitForMessages func returns.
|
||||||
|
sub.pDone = func(_ string) {
|
||||||
|
close(w.updates)
|
||||||
|
}
|
||||||
w.sub = sub
|
w.sub = sub
|
||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
@@ -454,6 +454,35 @@ func TestKeyValueWatch(t *testing.T) {
|
|||||||
expectOk(t, kv.Delete("age"))
|
expectOk(t, kv.Delete("age"))
|
||||||
expectDelete("age", 6)
|
expectDelete("age", 6)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("stop watcher should not block", func(t *testing.T) {
|
||||||
|
s := RunBasicJetStreamServer()
|
||||||
|
defer shutdownJSServerAndRemoveStorage(t, s)
|
||||||
|
|
||||||
|
nc, js := jsClient(t, s)
|
||||||
|
defer nc.Close()
|
||||||
|
|
||||||
|
kv, err := js.CreateKeyValue(&nats.KeyValueConfig{Bucket: "WATCH"})
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
watcher, err := kv.WatchAll()
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
expectInitDone := expectInitDoneF(t, watcher)
|
||||||
|
expectInitDone()
|
||||||
|
|
||||||
|
err = watcher.Stop()
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case _, ok := <-watcher.Updates():
|
||||||
|
if ok {
|
||||||
|
t.Fatalf("Expected channel to be closed")
|
||||||
|
}
|
||||||
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
t.Fatalf("Stop watcher did not return")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueWatchContext(t *testing.T) {
|
func TestKeyValueWatchContext(t *testing.T) {
|
||||||
|
@@ -625,6 +625,35 @@ func TestObjectWatch(t *testing.T) {
|
|||||||
expectOk(t, err)
|
expectOk(t, err)
|
||||||
expectUpdate("C")
|
expectUpdate("C")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("stop watcher should not block", func(t *testing.T) {
|
||||||
|
s := RunBasicJetStreamServer()
|
||||||
|
defer shutdownJSServerAndRemoveStorage(t, s)
|
||||||
|
|
||||||
|
nc, js := jsClient(t, s)
|
||||||
|
defer nc.Close()
|
||||||
|
|
||||||
|
obs, err := js.CreateObjectStore(&nats.ObjectStoreConfig{Bucket: "WATCH-TEST"})
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
watcher, err := obs.Watch()
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
expectInitDone := expectInitDoneF(t, watcher)
|
||||||
|
expectInitDone()
|
||||||
|
|
||||||
|
err = watcher.Stop()
|
||||||
|
expectOk(t, err)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case _, ok := <-watcher.Updates():
|
||||||
|
if ok {
|
||||||
|
t.Fatal("Expected channel to be closed")
|
||||||
|
}
|
||||||
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectLinks(t *testing.T) {
|
func TestObjectLinks(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user