Apollo-server: Support for node multi-cluster

Created on 7 Oct 2018  Â·  11Comments  Â·  Source: apollographql/apollo-server

I ran into an issue when using GraphQL subscriptions on a clustered node instance. The subscribing event only occurs on one instance of the node server. As a result, you will only receive updates that occur on that particular node instance.

  • [x ] has-reproduction

In order to reproduce, setup GraphQL subscriptions on a multi-core node instance. Start the instance with the pm2 -i 0 option like so
pm2 start index.js -i 0 -- start

Next, subscribe to an event
Finally, attempt to trigger that event several times. You will see that the subscription event will not always fire.

  • [x ] feature

    pubsub; subscriptions

All 11 comments

What is the OS?

Scott

NAME="Ubuntu"
VERSION="16.04.4 LTS (Xenial Xerus)"

Is there an update on this issue?

I'm checking back on this issue. Have their been any updates?

Thanks!

Which pubsub implementation are you using?

"graphql-subscriptions": "^0.5.8",

import { PubSub, withFilter } from 'graphql-subscriptions';
const uuid = require('node-uuid');
import { driver } from '../db/neo4j';
import { db } from '../db/firestore';
import { getQueue } from '../middleware/queue';
import { createDatePush } from '../middleware/createDatePush';
import { newMessagePush } from '../middleware/newMessagePush';
import { chooseWinnerPushWinner, chooseWinnerPushLoser } from '../middleware/chooseWinnerPush';
import { getCurrentDateFirestore, getCurrentDateNeo } from '../middleware/format';

const pubsub = new PubSub();
const session = driver.session();

const NEW_MESSAGE = 'NEW_MESSAGE';
const MESSAGE_PAGE_LENGTH = 20;
const QUEUE_PAGE_LENGTH = 5;
const MATCH_PAGE_LENGTH = 5;

const resolvers = {
    Subscription: {
        newMessageSub: {
            // The resolve method is executed after the subscribe method w/ filter
            resolve: (payload) => payload.newMessageSub.message,
            // For the withFilter function, the first argument is the tag that you are subscribing to.
            // The second argument is the filter.
            subscribe: withFilter(
                () => pubsub.asyncIterator(NEW_MESSAGE),
                (payload,args) => {
                    console.log('payload: ',payload);
                    console.log('args: ',args);
                    return (payload.newMessageSub.matchId === args.matchId && payload.newMessageSub.message.uid != args.id)
                }
            ),
        },
    },

So the PubSub from graphql-subscriptions is an in-memory one, so subscriptions made to a node will only receive updates on events that get published on that node, which explains your problem. But if you use something like graphql-redis-subscriptions and connect it to redis, then all of your nodes should share the same event source.

Ah, I see. I'll check that out.

Thanks for the help. You can close out this issue.

On Sat, Oct 27, 2018, 6:57 PM Keith Smith notifications@github.com wrote:

So the PubSub from graphql-subscriptions is an in-memory one, so
subscriptions made to a node will only receive updates on events that get
published on that node, which explains your problem. But if you use
something like graphql-redis-subscriptions
https://github.com/davidyaha/graphql-redis-subscriptions and connect it
to redis, then all of your nodes should share the same event source.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/apollographql/apollo-server/issues/1778#issuecomment-433662033,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABa5EXnHlMwuD9TB6pbWvLn5UeYUFFGhks5upOS_gaJpZM4XL12n
.

@cmcaboy it's been a long time, but have you managed to configure PM2 cluster mode and graphql-redis-subscriptions successfully? I'm still having an issue where subscriptions are working only on single Node instance.

@evenfrost Sorry to hear about your issue. Unfortunately, I ended up not taking that route. I just scaled the project back to a single instance. It was a personal side project so I really didn't need to the auto-scaling.

On a separate project, I was able to use socket.io with Redis on a multi-node configuration, but that was a non-graphql backend.

Got it, thanks for the response.

Was this page helpful?
0 / 5 - 0 ratings