-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
socket.reconnectStrategy
short circuits if no error listener is added to redis client.
#1993
Comments
we're experiencing the same issue, and this one seems to be related: #2032 we're stuck with v3 for now, although v4 would work, connection hiccups would affect our availability and v4 reconnect/recovery seems unreliable. hoping this gets fixed soon. |
omg thank you, i was so confused on why it wasn't reconnecting |
I was using [email protected] and I had this problem (with an error listener defined). I was using redis clients for an adapter in my socket.io server project, and I thought (incorrectly) that the error was in my configuration of the @socket.io/redis-adapter package. My subClient reconnected as expected, but the pubClient passed the 'reconnecting' and 'connect' events without ever entering the 'ready' hook. Downgrading redis to 3.1.2 fixed my problem immediately. |
+1 bump
Edit:
Just skimming: I'm thinking whoever wrote that line meant to put If that's not intended, I would bail/stop retrying after the X'th retry; I'll fork & PR a line change because this can't be fixed by defining a error handler. Edit 2: Line 42 in fe16dc0
Or I'm a idiot and this is 100% intended, both the |
Unfortunately, this is the approach we will also be using since constant socket closing event can’t be something we can rely in production. @rpong have you managed to resolve this issue or you ended up using v4 although you still experience this issue? |
This is a Node.js "feature"/design decision (and not something specific to "node-redis") - if an edit: we can change the event to "silent error" or something like that when there are no listeners, but this is not how things "should work" in the "node.js world".. |
@leibale I understand that it’s how event emitter works, but it’s a little unintuinitive since this didn’t happen in v3. Could you maybe tell us why it happens now? Is there some core architectural change in how node-redis works so this happens? |
@niksy in v3 the client is hiding (not emitting) the error... |
We've been noticing some connection issues in production and have decided to experiment with retrying connections via
socket.reconnectStrategy
. After adding in a simple retry strategy, I wrote a test to ensure that it was behaving the way I expected. To my surprise, thereconnectStrategy
was only being invoked once and not the several times that I had expected.After diving into the source code, I eventually realized it's because I wasn't registering a listener for the
'error'
event on the redis client.My investigation lead me down the following steps.
Retry logic entrypoint in redis socket:
https://github.com/redis/node-redis/blob/master/packages/client/lib/client/socket.ts#L100
Line that throws on first error in retry logic:
https://github.com/redis/node-redis/blob/master/packages/client/lib/client/socket.ts#L155
Listener of error event in retry logic of redis socket:
https://github.com/redis/node-redis/blob/master/packages/client/lib/client/index.ts#L277
Once I got here, I was expecting there to be another listener somewhere that was throwing. To my surprise, after debugging and inspecting
this.listeners('error')
on the instance of the RedisClient, I realized that there were no error event listeners on the RedisClient. After some quick internet searches, I found the following:https://nodejs.org/api/events.html#error-events
"If an EventEmitter does not have at least one listener registered for the 'error' event, and an 'error' event is emitted, the error is thrown."
So in order to get retrying to work without short-circuiting after the first error, we have to register an error event listener to prevent the calls to
this.emit('error', err)
from throwing errors.Example.
Example output.
Is this the behavior as intended? This is not mentioned anywhere in the docs, and it was confusing to me. I would have expected my reconnect strategy to work without requiring additional configuration, especially configuration that lives outside of the options object passed to the call to
createClient
.Environment:
v14.17.3
irrelevant
4.0.3
irrelevant
The text was updated successfully, but these errors were encountered: