I have an interesting conundrum; I use Redis PubSub pattern to emit events within my network of NodeJS microservices. I moved away from RabbitMQ because I needed the messages to be multi-cast, so that multiple microservices could receive and handle the same event. So if I emit a LOGOUT event, both the UserService and the WebSocketService should hear it.
This worked fine until my client deployed in an environment in which multiple instances of each microservice run. Now, given 3 instances of a UserService, all instances connect to Redis and they all receive and handle the LOGOUT event, which is bad.
So on one hand I need the distinct microservices to hear the event, but on the other I need to prevent the duplicate copies of the same microservice from all handling the event. Rock, meet hard place.
My best thinking so far is a bit hacky, but something like:
- Instead of raising events, write to the Redis cache a list of events
- The UserService and WebSocketService could read that list once every 3 seconds and check for new events that need handling
- When a relevant event is found, UserService would add its "name" to the list of services that is handling the event
- When WebSocketService sees the event, it will still be able to handle it and add its "name" to the handlers list
- When a duplicate instance of UserService sees the event, it will see its "name" already in the list of handlers and ignore that event
I don't love this solution because the list will be ever-growing in memory rather than in a transient message. Also I'll have to start adding code to manage which events have already been checked; otherwise every cycle, the whole list would have to be parsed again by all instances of all services.
Ideas welcome.
