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

Redis setEX Expired Event Triggering Multiple Times Despite Unsubscribe/Resubscribe #13248

Open
Prem-Kumar-98 opened this issue May 5, 2024 · 9 comments

Comments

@Prem-Kumar-98
Copy link

Problem:
In a Redis setup, utilizing setEX to set a key with an expiration time, I've encountered an issue where the expired event is triggered multiple times for the same key if the channel is subscribed to multiple times. Despite attempting to mitigate this by unsubscribing and then resubscribing to the channel, the expired event still occasionally fires twice.

Details:

  • node-redis client version: 4.6.7
  • Redis version 6.x
  • The process involves setting a key with a defined expiration time using setEX.
  • Upon expiration, an event is triggered on a subscribed channel.
  • If the channel is subscribed to multiple times, the expired event may be emitted multiple times.
  • To address this, unsubscribing from the channel before resubscribing is attempted as a workaround.
  • Despite implementing this workaround, there are instances where the expired event is still triggered twice.

Expected Behavior:
The expired event should only be triggered once, regardless of how many times the channel is subscribed to.

Additional Information:

  • I've ensured that the unsubscribe/resubscribe logic is correctly implemented.
  • This issue occurs sporadically and is difficult to replicate consistently.
  • Any insights or suggestions on why the expired event might be firing twice, despite attempts to prevent it, would be greatly appreciated.
@sundb
Copy link
Collaborator

sundb commented May 6, 2024

@Prem-Kumar-98 can you share your test code?
from my testing it's generally not a redis issue, maybe relate to client.

@Prem-Kumar-98
Copy link
Author

Hi @sundb ,
Below is the code snippet for the test method as requested. I've replaced sensitive information with generic placeholders for confidentiality:

Class exampleFileName(){

Constructor() {
    this.client = RedisInstance.getRedis();
    this.redisService = RedisSubscriberClient.getRedis();
}

async testMethod() {
  await this.client.unsubscribe("__keyspace@0__:" + timerKey);
  await this.redisService.setex("__keyspace@0__:" + timerKey, 60);
  this.client.subscribe("__keyspace@0__:" + timerKey, (message, channel) => {
    console.log("Testing event triggered", message, channel);
  }).then((response) => {
    log.info("Timer set! " + response);
  });
}
}

Let me know if you need further assistance or clarification.
I have a question regarding the behavior of a node-redis client. If a node-redis client subscribes to a channel twice with different instances, will it emit the expired event twice?

@sundb
Copy link
Collaborator

sundb commented May 7, 2024

I have a question regarding the behavior of a node-redis client. If a node-redis client subscribes to a channel twice with different instances, will it emit the expired event twice?

yes, they are two connections.

@Prem-Kumar-98
Copy link
Author

Prem-Kumar-98 commented May 7, 2024

So, as you can see, i'm unsubscribing the channel before subscribing to it. In this case, why is the expired event emitting twice in the rarest case?

@sundb
Copy link
Collaborator

sundb commented May 7, 2024

@Prem-Kumar-98 can you share the notificatiions you received?

@Prem-Kumar-98
Copy link
Author

Hi @sundb , I don’t have logs or notification details. I'm using GCP Redis Labs, and I could see the subscribed callback got triggered twice.

  this.client.subscribe("__keyspace@0__:" + timerKey, (message, channel) => {
    console.log("Testing event triggered", message, channel);
  })

@sundb
Copy link
Collaborator

sundb commented May 7, 2024

@Prem-Kumar-98 what's your config notify-keyspace-events?
first at all, if you are using KEA, the script you give will receive three notification:

__keyspace@0__k set
__keyspace@0__k expire
__keyspace@0__k expired

@Prem-Kumar-98
Copy link
Author

@sundb ,Keyspace event I configured the cloud service and verified that with the configuration I have from my end, it will emit the event only for expired, because it's not happening all the time; in the rarest case, it's emitting the expired events twice.

@sundb
Copy link
Collaborator

sundb commented May 8, 2024

@Prem-Kumar-98 sorry, from the clues i don't know the reason.
go through the code, the expired notification was just send from one place, at the same we will remove it from the database.
i don't think one key can be expred two times.

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