Skip to content

Commit a76dcd6

Browse files
committed
bugfix: watcher events loss
Watchers may behave incorrectly if a request timeout is too small. A re-IPROTO_WATCH request may be not send to a server. It could lead to loss of events stream. It also could lead to a lost IPROTO_UNREGISTER request, but a user won't see the problem. Closes #284
1 parent 986a9a1 commit a76dcd6

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
2323
- Several non-critical data race issues (#218)
2424
- ConnectionPool does not properly handle disconnection with Opts.Reconnect
2525
set (#272)
26+
- Watcher events loss with a small per-request timeout (#284)
2627

2728
## [1.10.0] - 2022-12-31
2829

connection.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -1456,10 +1456,13 @@ func (conn *Connection) newWatcherImpl(key string, callback WatchCallback) (Watc
14561456
st <- state
14571457

14581458
if sendAck {
1459-
conn.Do(newWatchRequest(key)).Get()
14601459
// We expect a reconnect and re-subscribe if it fails to
14611460
// send the watch request. So it looks ok do not check a
1462-
// result.
1461+
// result. But we need to make sure that the re-watch
1462+
// request will not be finished by a small per-request
1463+
// timeout.
1464+
req := newWatchRequest(key).Context(context.Background())
1465+
conn.Do(req).Get()
14631466
}
14641467
}
14651468

@@ -1477,7 +1480,12 @@ func (conn *Connection) newWatcherImpl(key string, callback WatchCallback) (Watc
14771480
if !conn.ClosedNow() {
14781481
// conn.ClosedNow() check is a workaround for calling
14791482
// Unregister from connectionClose().
1480-
conn.Do(newUnwatchRequest(key)).Get()
1483+
//
1484+
// We need to make sure that the unwatch request will
1485+
// not be finished by a small per-request timeout to
1486+
// avoid lost of the request.
1487+
req := newUnwatchRequest(key).Context(context.Background())
1488+
conn.Do(req).Get()
14811489
}
14821490
conn.watchMap.Delete(key)
14831491
close(state.unready)

0 commit comments

Comments
 (0)