Skip to content

fix(internal/pool): call SetDeadline even if timeout is zero #2176

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

Merged
merged 2 commits into from
Oct 5, 2022

Conversation

j178
Copy link
Contributor

@j178 j178 commented Aug 3, 2022

This PR revert #2060, which caused #2175.

Fixes #2175.

@j178 j178 force-pushed the fix-read-timeout branch from 936b3d0 to 2123e08 Compare August 4, 2022 03:22
if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil {
return err
}
if err := cn.netConn.SetReadDeadline(cn.deadline(ctx, timeout)); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be timeout >= 0 so it works with PubSub

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the pubsub.ReceiveTimeout(ctx, timeout) case, we don't say anything about the timeout argument, is it intended to ignore negative timeout?

for example pubsub.ReceiveTimeout(ctx, -1) means do not set a deadline, use the previous set deadline ?

_, _ = pubsub.ReceiveTimeout(ctx, 3*time.Second) // this call set the deadline to time.Now().Add(3*time.Second)
time.Sleep(3)
_, _ = pubsub.ReceiveTimeout(ctx, -1) // this call will timeout immediately, but it may be intended to block forever

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReceiveTimeout(0) is the same as Receive() which means block forever. Negative values should probably disable Set*Deadline calls completely.

But I admit it is subtle.

options.go Outdated
@@ -76,7 +76,7 @@ type Options struct {
// Default is 3 seconds.
ReadTimeout time.Duration
// Timeout for socket writes. If reached, commands will fail
// with a timeout instead of blocking.
// with a timeout instead of blocking. Use value -1 for no timeout and 0 for default.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 for no timeout is meant to disable the timeout, but it looks like you always call SetReadDeadline no matter what. Perhaps the comment must be updated?

Copy link
Contributor Author

@j178 j178 Aug 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is copied from the ReadTimeout description above.
I think no timeout == disable the timeout == block until read/write succeeds, do I understand this correctly?

-1 will be adjusted to 0 here: https://github.com/go-redis/redis/blob/084c0c8914d4d84918a81b867b61d94b6c343ecd/options.go#L152-L157
then in SetReadDeadline or SetWriteDeadline, the timeout is diabled, and the read/write operation will block until it succeeds.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct, but it looks like we should also support -2 to disable Set*Deadline calls completely.

@woutslakhorst
Copy link

I can confirm this also fixes the disconnect behaviour when using Redis sentinel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pubsub.Receive() will timeout
3 participants