Class: GraphQL::Streaming::ActionCableCollector

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/streaming/action_cable_collector.rb

Overview

Accept patches from GraphQL and send them to clients via ‘channel_name`.

Patches are also issued with ‘query_id`. This way, clients on the same channel can tell whether a patch is for their query or someone else’s.

When a query is finished (no more patches will be sent), the collector can notify clients with #close

Examples:

Sending patches over ActionCable

# Use this middleware to close queries when they're finished:
MySchema.middleware << GraphQL::Streaming::ActionCableMiddleware.new

class GraphqlChannel < ApplicationCable::Channel
  # Implement `#fetch(data)`, which corresponds with GraphQLCable client
  def fetch(data)
    query_string = data["query"]
    variables = ensure_hash(data["variables"] || {})

    # build a collector including `query_id`
    # which comes from GraphQLCable client
    broadcaster = ActionCable.server.broadcaster_for(channel_name)
    query_id = query_id = data["query_id"]
    collector = GraphQL::Streaming::ActionCableCollector.new(query_id, broadcaster)

    context = { collector: collector }
    Schema.execute(query_string, variables: variables, context: context)
  end
end

Tell the client to stop listening for patches

collector = GraphQL::Streaming::ActionCableCollector.new(query_id, broadcaster)
# ...
collector.close

Instance Method Summary collapse

Constructor Details

#initialize(channel, query_id) ⇒ ActionCableCollector

Returns a new instance of ActionCableCollector.

Parameters:

  • A (String)

    unique identifier for this query (probably provided by the client)

  • The (ActionCable::Server::Broadcasting::Broadcaster)

    broadcast target for GraphQL’s patches



41
42
43
44
45
# File 'lib/graphql/streaming/action_cable_collector.rb', line 41

def initialize(channel, query_id)
  @query_id = query_id
  @channel = channel
  @closed = false
end

Instance Method Details

#closevoid

This method returns an undefined value.

Broadcast a message to terminate listeners on this query



64
65
66
67
68
69
70
# File 'lib/graphql/streaming/action_cable_collector.rb', line 64

def close
  @channel.send_graphql_payload({
    query_id: @query_id,
    close: true,
  })
  @closed = true
end

#patch(path:, value:) ⇒ void

This method returns an undefined value.

Implements the “collector” API for DeferredExecution. Sends ‘{…, query_id: @query_id}` over `@broadcaster`.



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/graphql/streaming/action_cable_collector.rb', line 50

def patch(path:, value:)
  if !@closed
    @channel.send_graphql_payload({
      query_id: @query_id,
      patch: {
        path: path,
        value: value,
      },
    })
  end
end