I have my backend replicas in order to provide horizontal scaling. Back end has apollo graphql subscriptions. There is also a microservice providing notifications for particular subscriptions.
Since I don't keep any state in backend, I've tried to solve the problem with implementing Redis PUB/SUB. When microservice receives an event, it will publish to backends.
In the subscription resolver of back end I have
webhookCalled: {
subscribe: withFilter(
() => pubsubMyEvent.asyncIterator([MY_EVENT]),
(payload, _, context) => {
return context.dataValues.id == payload.userid;
}
)
}
In above code I am trying to filter out subscriptions that payload is not addressed to. I am not so sure how costly is withFilter
routine.
When I receive PUB from Redis am calling
pubsubMyEvent.publish(MY_EVENT, { myEventData });
What I don't like here is that each back will process(publish(...)
) all events, even if at the end only one backend will actually send the subscription message to graphql client.
Question: how can I efficiently handle sending events to graphql subscription clients, while having scalable back end? Perhaps not to bother all back end copies, when single websocket connection need to be notified. Should I keep track of all connected clients in Redis so Redis knows where each graphql subscription client is connected?