Graphql-ruby: Subscription Triggers Do Nothing with ActionCable

Created on 6 Feb 2020  路  17Comments  路  Source: rmosolgo/graphql-ruby

Hi! Thanks a lot for this awesome library and thanks in advance for the help.

I am using v1.9.15

We've been working with graphql-ruby in our app with Apollo on the frontend for quite awhile, and are currently in the process of implementing subscriptions for the first time. Since we are only planning on using a few subscriptions, we thought ActionCable would be an easy choice for the websocket server.

I'm able to establish a connection and I see ongoing pings on the client letting me know that my connection is remaining open. I'm reaching an impasse, though, when attempting to use MySchema.trigger to pass messages to the subscribed client. My subscription type looks like this:

module Types
  class SubscriptionType < GraphQL::Schema::Object
    field  login_response, subscription: Subscriptions::LoginResponse,
      null: false,
      description: "FILL THIS IN"
  end
end

and the specific subscription in question looks like this:

module Types
  class LoginResponse < Types::BaseObject
    field :accounts, [Types::ThirdPartyAccount], null: true,
                                             description: 'third-party login was successful'

    field :mfa_challenge, Types::MfaChallenge, null: true
  end
end

I am attempting to trigger in a mutation like this:

AppSchema.subscriptions.trigger('loginResponse', {}, ThirdPartyAccount.last(2))

This trigger call logs out the following:

[ActionCable] Broadcasting to graphql-event::loginResponse:: "[{\"__gid__\":\"Z2lkOi8vcG9vbC9MaW5rZWRBY2NvdW50LzMw\"},{\"__gid__\":\"Z2lkOi8vcG9vbC9MaW5rZWRBY2NvdW50LzMx\"}]"

At this point nothing arrives on the client. I've tried scoping the subscription field and passing the associated scope: option to trigger per the guides and I've used the Redis and Async adapters but nothing seems to work. Any help is greatly appreciated!

Most helpful comment

Sorry about the trouble 馃槚 In your root Subscription type, do you have

extend GraphQL::Subscriptions::SubscriptionRoot

? It's required for the new interpreter runtime, so you might have to add it.

I _think_ it can be refactored so that the extend is not required, so if that fixes it, I'll look into it!

All 17 comments

Screenshot of the type of thing I'm seeing logged from my websocket connection on the client:
Screen Shot 2020-02-05 at 5 23 18 PM

I also ran a bundle update graphql to get the latest version and I'm still experiencing the same issue.

Thanks for building this - I'm loving it so far. I'm also running into this issue. Exact same for me. Trigger logs:

[ActionCable] Broadcasting to graphql-event::identityCreated:: "{\"__gid__\":\"Z2lkOi8vYXBpL0lkZW50aXR5LzE\"}"

But nothing happens after that. I've followed all the tutorials and used the async and redis adapters.

One thing I've noticed is that a stream does not ever seem to be created. When the subscription triggers I see the following in the rails server but never a stream begin.

GraphqlChannel transmitting {:result=>{"data"=>{"identityCreated"=>{"waitListCount"=>233, "__typename"=>"IdentityCreatedPayload"}}}, :more=>true}

In this tutorial, in the "Realtime Updates!" section, it shows this screenshot:

pic

It seems that channel should start a stream but that never happens for me.

Any suggestions?

Sorry about the trouble 馃槚 In your root Subscription type, do you have

extend GraphQL::Subscriptions::SubscriptionRoot

? It's required for the new interpreter runtime, so you might have to add it.

I _think_ it can be refactored so that the extend is not required, so if that fixes it, I'll look into it!

I completely missed that! Thank you for responding. That fixed the issue for me. Very excited! Thanks again for building this amazing library!

Thanks for the help @rmosolgo. I have tried following the instructions for the new interpreter and added the extend GraphQL::Subscriptions::SubscriptionRoot to my SubscriptionType but I still don't seem to be able to get a stream.

@macgill4444 seeing as we have similar setups and were experiencing similar issues but you were able to get it working would you be open to sharing a bit more detail on how you have things set up and how you're testing the subscription? Thanks a lot.

@macgill4444 if you're in the GraphQL slack you can get me @Doug Mill if that's easier and if I can get it working I will post whatever I found back into this issue.

@dmill most definitely. Will do right now!

Thanks! That helps me too! :) I've missed up the extend when I read the documentation.

Okay I was able to get this working as well after going back through the docs with a fine-toothed comb. Thanks again everyone! @rmosolgo happy to close this unless you'd like to leave it open if there are some changes to the docs that could make this easier. Let me know if I can assist in any way.

Let me keep it open for a minute -- I'd love to make it so that the extend wasn't necessary, I just have to find some shenanigans to make it work.

Okay sounds good.

Hey, I'm having the same issue. My fine toothed comb must be broken, @dmill can you share what you discovered?

I see that action_cable_subscriptions is the only place we call channel.stream_from, which in turn is called by subscription/instrumentation.rb after_query

      # After checking the root fields, pass the gathered events to the store
      def after_query(query)
        events = query.context.namespace(:subscriptions)[:events]
        if events && events.any?
          @schema.subscriptions.write_subscription(query, events)
        end
      end

but I have no events in my context... what am I missing?

Hey @chandeeland - for me it turned out that I had two issues, the first being the main problem discussed in this issue and the second being a mismatch between the format of the subscription I was sending from the client and the fields I had set up on the server. It seems that a number of errors like this won't really get surfaced, but will manifest by the lack of streaming that I was experiencing here.

So, I was able to get a subscription and a stream working, and I was able to use .trigger to transmit messages to the client, but unfortunately I wound up running into another issue where I was unable to send any actual subscription data - the payload would just land on the client with data: null. I'm sure something else was misconfigured, but we decided we were sinking too much time into this digging for issues so we ditched it and switched to Pusher.

@dmill

I came to this issue for the same problem. I could run subscription and trigger, and here's the bare minimum project.

https://github.com/github0013/graphql-ruby-bare-min/tree/master

Hope this help anyone who comes for the same issue.

I had similar problem which trigger the Subscription.update, but react app won't receive the update. Which was due to the serialisation failed:

MySchema.subscriptions.trigger("modelUpdated", {}, myAwsRecordModel)

I added to_h to convert to a simpler structure which worked:

MySchema.subscriptions.trigger("modelUpdated", {}, myAwsRecordModel.to_h)

Hope it helps for some friends!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sayduck-daniel picture sayduck-daniel  路  3Comments

ecomuere picture ecomuere  路  3Comments

jesster2k10 picture jesster2k10  路  3Comments

Plummat picture Plummat  路  4Comments

pareeohnos picture pareeohnos  路  3Comments