-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to gracefully close connections blocked on reading from Redis streams? #933
Comments
Do you suggest we use CloseRead when closing the connection pool? The alternative is to add some guard against closing the connection twice which should be trivial and conceptually simpler. |
In the example scenario I mentioned above, if we can avoid closing the connection twice, I think it's ok to use the existing client.Close(). There is another scenario, in theory, where a connection may be shared by two processes (e.g. both are blocked on reading from the same connection). Then client.CloseRead() can unblock both processes, while client.Close() can only unblock the process where it is called within. That being said, I have little experience with the latter scenario in Golang, so I don't know if it's a practical problem.
Yeah, for the example scenario, I think the alternative solution is good. Maybe we can check the error string "use of closed network connection" (which is an internal error ErrNetClosing) before closing the connection? |
This issue suggests that closing fd twice is fine in most cases. We still can add some checks but it looks like there is no real problem here . |
Yeah, I agree. The problem of Unix's close:
is due to its manipulation on the raw fd. But in Go, the raw id is wrapped in an implementation of Conn (e.g. TCPConn), which will do some check to ensure the safety to be closed twice or more. @vmihailenco Thanks for your reply. I'm going to close this issue. |
Question
Per the documentation of XREAD:
In other words, it's recommended to use the blocking mode while reading from Redis streams.
When using go-redis, we may write the following code:
Then there is a question: how to gracefully close the blocking connection?
The problem of client.Close()
In the example code, If we use
client.Close()
to close the connection, it will cause an error log:What happened behind
client.Close()
is as follows:client.Close()
will close the connection poolclient.XRead()
, which is blocking on cn.WithReader(), will be unblocked and returns an error "use of closed network connection"c.releaseConn()
will be called, and err is judged as a bad one, which will finally closes the connection againThe real problem is:
There was a discussion about the same issue on StackOverflow.
Possible solution
Use TCPConn.CloseRead or UnixConn.CloseRead, which are the Golang's equivalents of Unix's
shutdown()
.Then we need to add a function
CloseRead()
into redis.Client.Any other thoughts?
The text was updated successfully, but these errors were encountered: