Skip to content

Commit

Permalink
[FIXED] Repeated timeout of Flush/FlushTimeout and inability to dispatch
Browse files Browse the repository at this point in the history
If when the client issues a Flush() or FlushTimeout(), the client
library times out when at the same time it receives the PONG, there
is a possibility that the processing of the PONG gets the channel
it needs to notify from the array while the routine waiting on
that notification is done waiting but has not yet removed the
channel from the array. This will lead to processPong() to be
stuck in a chan send, which is blocking the readLopp, which will
ultimately lead to server closing this connection.

The solution is to create a buffererd channel (of size 1). We
should not simply do a `select` when trying to notify because we
don't want to miss the notification if the routine sending the PING
is not yet in the select to consume the notification.

Resolves #321
  • Loading branch information
kozlovic committed Oct 13, 2017
1 parent 4b47946 commit 7239a8e
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion nats.go
Expand Up @@ -2670,7 +2670,10 @@ func (nc *Conn) FlushTimeout(timeout time.Duration) (err error) {
t := globalTimerPool.Get(timeout)
defer globalTimerPool.Put(t)

ch := make(chan struct{})
// Create a buffered channel to prevent chan send to block
// in processPong() if this code here times out just when
// PONG was received.
ch := make(chan struct{}, 1)
nc.sendPing(ch)
nc.mu.Unlock()

Expand Down

0 comments on commit 7239a8e

Please sign in to comment.