graphql-subscriptions: graphql-subscriptions is not working consistently.

Hi all, We are using PubSub in our application in this manner:

When deletion event is arriving into server: pubsub.publish('onDeleteItem', {onDeleteItem: [msg.payload.ItemId]});

Resolvers: Subscription: { onDeleteItem: { subscribe: () => pubsub.asyncIterator('onDeleteItem'), }, },

Subscribing to it from our client side: const onDeleteItemSubscription = gql

          subscription onDeleteItem {
                onDeleteItem
  }

getItemsList () {
  queryRef.subscribeToMore({
      document: onDeleteItemSubscription ,
      updateQuery(prev: { itemList: AssetList }, {subscriptionData: {data}}) {
        if (!data) {
          return prev;
        } else {
          const deletedItems = (data as any).onDeleteItem;
          return {
                   itemList {...    ### //return filtered list
                       }
            } 
          } 
       }
    }

;

The problem is that sometimes the subscription is working fine and the deleted item is filtered as expected, but very often it just not working at all. There are no error logs. When I debug it, I can see that the problem is that the client is not notified by pubsub.publish()

The problem is occurring with all our subscriptions and this is only one example of them.

What am I missing here? Thanks.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 32
  • Comments: 39 (1 by maintainers)

Most upvoted comments

We had something similar. Everything worked local, but not on production. The problem was that we had 2 scaled server instances running. So it only worked 50% of the time because the Pubsub has to be on the same server instance

August 11, 2020: Did anyone ever figured this?

It used to work well (sometimes) but has currently stopped working for the chat section of my app, even on local.

Same here with PM2 cluster mode and graphql-redis-subscriptions over Redis. Subscriptions still work on single node instead of all.

Having this same issue, sometimes the subscription just doesn’t trigger on the app end

having the same issue on AWS. using multiple instances and it works perfectly local but not in production. Using graphql-redis-subscriptions and ioredis for multi instances.

import { RedisPubSub } from 'graphql-redis-subscriptions';
import Redis from 'ioredis';

const options = {
  host: process.env.REDIS_HOST,
  port: process.env.REDIS_PORT,
  password: process.env.REDIS_PASSWORD,
  retryStrategy: times => {
    return Math.min(times * 50, 2000);
  }
};

const pubsub = new RedisPubSub({
  publisher: new Redis(options),
  subscriber: new Redis(options)
});

export default pubsub;

the error I see in the playground:

{ “error”: “Could not connect to websocket endpoint wss://…/graphql. Please check if the endpoint url is correct.” }

We have same issue in production with the following stack:

  • redis pubsub graphql-redis-subscriptions
  • ioredis
  • apollo-server
  • apollo-client
  • react

Redis & apollo server are on separate VMs.

Our team gave up on waiting for a fix here and made the switch to graphql-ws for our subscriptions, but still using the PubSub from this package. We have not this issue since, and it only took a little bit of effort to adapt the client code, since they have an example for just about every client you can imagine. The main drawback is that the GraphQL playground/sandbox doesn’t support it natively yet.

We still have strange issues here in production causing from memory-leaks (using Websockets) and gentleman, it is really not a pleasure to fix such a problem. We ended up by making use of polling as a first hot fix, furthermore we have noticed same strange behaviour in our connector implementation https://github.com/axelspringer/graphql-google-pubsub/issues/16. Contributors are scratching behind their heads, developers are catching after ghosts. From our side, we do not trust the whole async iterator stuff at the moment.

So yes, my issue ended up being we weren’t’ closing subscriptions when we closed the component. So we would keep opening new subscriptions and the server couldn’t manage all the subscriptions. (all the subscriptions came in the same socket)

Bumping this up as we are experiencing similar behaviour with some of the clients missing subscription messages without a reproducible pattern.

Same Issue here. Subscriptions work sometime and other times they just refuse to connect and show the following error: { “error”: “Could not connect to websocket endpoint ws://****/graphql. Please check if the endpoint url is correct.” }

Okay so I sort of found out what my issue was, and it wasn’t headers. Strangely, node version seems to have been the culprit.

Locally I was working with 12.16.1, or so node --version says. My dev ec2 instance was on 14. I compared the object returned by redis.asyncIterator("TEST") locally and on my instance, and they were almost the same except for a few stuff, including a property that was missing on the server: [Symbol(kCapture)]: false.

It’s slightly confusing though because sudo node --version returns 14, and without sudo it returns 8.10 (ec2 instance). So to be honest, I’m not sure which one my app was using using. I found this: https://github.com/nodejs/node/issues/31787 so I just decided to test it. I installed the same node version on the server as my local, 12.16.1 and forced it to use it for both root and non-root, and voila! Subscriptions started working again.

I found where the function that throws the error above (https://github.com/graphql/graphql-js/blob/master/src/subscription/subscribe.js#L287) and how they determine whether an object is an async iterator or not (https://github.com/graphql/graphql-js/blob/35f6df8693eaf9f484df8566f752a515aee4893b/src/jsutils/isAsyncIterable.js#L11).

I’m not a js developer so I don’t know what any of this means, but it’s working now after explicitly setting node to 12.16.1.

Very scientific analysis, I know.

having the same issue…