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

Subscriber clients won't reconnect #1451

Closed
xairoo opened this issue Oct 29, 2021 · 8 comments
Closed

Subscriber clients won't reconnect #1451

xairoo opened this issue Oct 29, 2021 · 8 comments

Comments

@xairoo
Copy link

xairoo commented Oct 29, 2021

Subscriber clients won't reconnect after a timeout when redis server removes the client based on tcp-keepalive setting (default is 300 seconds).

This is only related to a remote redis connection. Locally it works.
I ran into this because I put my system to sleep instead of shutting it down. But instead of sleep it could be a broken uplink, switch failure, power outage and so on.

The subscriber should automatically reconnect, but in this case he doesn't.

Reproduce

  • Use a remote redis server
  • Cut your uplink for at least 300 seconds (tcp-keepalive value) or put your system to sleep/hibernate
    • You can reduce this time when you reduce the tcp-keepalive value on your redis server
const Redis = require("ioredis");

(async () => {
  const client = new Redis({
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
    username: process.env.REDIS_USERNAME,
    password: process.env.REDIS_PASSWORD,
  });

  client.on("error", (err) => {
    console.log("client error", new Date(), err);
  });

  const publisher = new Redis({
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
    username: process.env.REDIS_USERNAME,
    password: process.env.REDIS_PASSWORD,
  });

  publisher.on("error", (err) =>
    console.log("publisher error", new Date(), err)
  );

  const subscriber = new Redis({
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
    username: process.env.REDIS_USERNAME,
    password: process.env.REDIS_PASSWORD,
  });

  subscriber.on("error", (err) => {
    console.log("subscriber error", new Date(), err);
  });

  subscriber.subscribe("ioredis:msg");

  subscriber.on("message", (channel, message) => {
    console.log(new Date(), message);
  });

  setInterval(() => {
    publisher.publish("ioredis:msg", "published @ " + new Date());
  }, 2500);
})();

I noticed that the error event for the subscriber doesn't get fired every time.

subscriber.on("error", (err) => {
  console.log("subscriber error", new Date(), err);
});
If it would, I could initiate the ping from from there.

My working fix

Ping the server regularly.

setInterval(() => {
  subscriber.ping()
}, 2500);
@marcbachmann
Copy link
Collaborator

The issue is most likely that there's no keepAlive configured. And for the keepalive itself we have another issue open: #1339

@marcbachmann
Copy link
Collaborator

question is why isn't a connection abort detected? I think it should resubscribe.
Sorry, will reopen that.

@marcbachmann marcbachmann reopened this Mar 26, 2022
@marcbachmann
Copy link
Collaborator

marcbachmann commented Mar 26, 2022

Could you test that with ioredis v5? most likely we don't know about the disconnect until some I/O happens. Fixing keepalive should get that working more reliably.

@Mall0c
Copy link

Mall0c commented May 25, 2022

Is this somehow tackled at the moment? The README says that a subscribed client will resubscribe to a channel, but for this the connection loss must be detected. The ping trick does its thing, but it would be cooler if a connection loss would be detected.

@marcbachmann
Copy link
Collaborator

marcbachmann commented May 25, 2022

A fix for the keepalive landed on the 31. of march #1554
Did you run into the same issue?

@Mall0c
Copy link

Mall0c commented May 30, 2022

Ah I see. We use node.js LTS Version, which is 16.x. AFAICT, this would work with node >= 17.7.0, right?

@marcbachmann
Copy link
Collaborator

marcbachmann commented May 30, 2022

The applied fix in ioredis v5.0.3 should work for all the node.js versions.
The mention of 17.7 was just about another new configuration option in the socket api, but that's not in use at the moment.

@marcbachmann
Copy link
Collaborator

Closing as we can assume the keepalive change fixed it

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

3 participants