Skip to content
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

redisAsyncConnect may get stuck connecting on Windows #817

Closed
jtanx opened this issue May 21, 2020 · 1 comment
Closed

redisAsyncConnect may get stuck connecting on Windows #817

jtanx opened this issue May 21, 2020 · 1 comment
Assignees

Comments

@jtanx
Copy link

jtanx commented May 21, 2020

I'm using the libuv example with MSVC 2017, but I think this applies to any that use the async model.

If you specify a connection that does not exist (and assuming you don't run into #785), then instead of calling the disconnect callback because the connection was refused, hiredis continues to try to connect when the event library (libuv in this case) signals the socket.

From what I can see, when signaling the socket, redisAsyncHandleWrite is called, which then calls __redisAsyncHandleConnect, and then redisCheckConnectDone, which then calls connect. But connect always returns EWOULDBLOCK, which redisCheckConnectDone happily accepts.

This causes the event library to signal the socket again, with the connect cycle repeated endlessly.

I think the key for this is described on WSAConnect

If the return error code indicates the connection attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the application can call WSAConnect again for the same socket.

I don't quite know where the error would be with IOCP (which I believe libuv uses), but I do know if you use WSAAsyncSelect, then the error code is returned as part of the callback when signaling the socket.

But in other words, by the time the socket is signaled, I think the connection has been refused, and so if you call connect again, it will retry the connection.

What I don't understand is why __redisAsyncHandleConnect needs to call redisCheckConnectDone (which then calls connect) at all; by that point, connect has already been called, so why can't it call redisCheckSocketError (which calls getsockopt) directly?

@michael-grunder michael-grunder self-assigned this May 21, 2020
@michael-grunder
Copy link
Collaborator

Closing this in favor of #930

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

No branches or pull requests

2 participants