Class: Rails::GraphQL::Subscription::Provider::ActionCable

Inherits:
Base
  • Object
show all
Defined in:
lib/rails/graphql/subscription/provider/action_cable.rb

Overview

GraphQL Action Cable Subscription Provider

The subscription provider associated with Rails Action Cable, that delivers subscription notifications through an Action Cable Channel TODO: Try to serialize and deserialize the origin

Constant Summary collapse

INTERNAL_CHANNEL =
'rails-graphql:events'

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

async_exec, new, #unsubscribed_payload, #unsubscribing?

Constructor Details

#initialize(*args, **options) ⇒ ActionCable

Returns a new instance of ActionCable.



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 19

def initialize(*args, **options)
  @cable = options.fetch(:cable, ::ActionCable)
  @prefix = options.fetch(:prefix, 'rails-graphql')

  @event_callback = ->(message) do
    method_name, args, xargs = Marshal.load(message)
    @mutex.synchronize { send(method_name, *args, **xargs) }
  end

  super
end

Instance Attribute Details

#cableObject (readonly)

Returns the value of attribute cable.



17
18
19
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 17

def cable
  @cable
end

#prefixObject (readonly)

Returns the value of attribute prefix.



17
18
19
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 17

def prefix
  @prefix
end

Instance Method Details

#accepts?(operation) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 35

def accepts?(operation)
  operation.request.origin.is_a?(::ActionCable::Channel::Base)
end

#add(*subscriptions) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 39

def add(*subscriptions)
  with_pubsub do
    subscriptions.each do |item|
      log(:added, item)
      store.add(item)
      stream_from(item)
    end
  end
end

#async_remove(item) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 49

def async_remove(item)
  return if (item = store.fetch(item)).nil?
  cable.server.broadcast(stream_name(item), unsubscribed_payload)
  store.remove(item)

  log(:removed, item)
end

#async_update(item, data = nil, **xargs) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 57

def async_update(item, data = nil, **xargs)
  return if (item = store.fetch(item)).nil?
  removing = false

  log(:updated, item) do
    data = execute(item, **xargs) if data.nil?
    store.update!(item)

    unless (removing = unsubscribing?(data))
      data = { 'result' => data, 'more' => true }
      cable.server.broadcast(stream_name(item), data)
    end
  end

  async_remove(item) if removing
end

#shutdownObject



31
32
33
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 31

def shutdown
  @pubsub = nil
end

#stream_name(item) ⇒ Object



74
75
76
# File 'lib/rails/graphql/subscription/provider/action_cable.rb', line 74

def stream_name(item)
  "#{prefix}:#{item.sid}"
end