TransWikia.com

How to publish effectively to graphql subscribers when backend scaled

Stack Overflow Asked on January 17, 2021

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?

enter image description here

One Answer

To send the published event to all the clients subscribed to the same channel is in the nature of redis.

A possible solution keeping the same architecture could be using a different channel for each user rather than using only one channel. The backed should subscribe to channel MY_EVENT + user.uuid once a new user connect and unsubscribe from same channel once the user disconnected. On the other side, the service, once webhook is called should publish not on the global channel but on MY_EVENT + user.uuid channel.

Correct answer by Daniele Ricci on January 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP