Class: Rails::GraphQL::Subscription::Provider::Base

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

Overview

GraphQL Base Subscription Provider

The base class for all the other subscription providers, which defines the necessary interfaces to install and stream the subscription to their right places

As a way to properly support ActiveRecord objects as part of the scope in a way that does not require queries and instance, a hash scope, where we have the class as the key and one or more ids as values, must be supported. In general, a implementation using .hash is recommended because User.find(1).hash == User.class.hash ^ 1.hash

Direct Known Subclasses

ActionCable

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Base

Returns a new instance of Base.



62
63
64
65
66
67
68
# File 'lib/rails/graphql/subscription/provider/base.rb', line 62

def initialize(**options)
  @store = options.fetch(:store, Store::Memory.new)
  @logger = options.fetch(:logger, GraphQL.logger)
  @mutex = Mutex.new

  validate!
end

Class Method Details

.async_exec(*method_names) ⇒ Object

Make sure to run the provided methods in async mode. Use the lock to identify if it’s already running in async or not



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rails/graphql/subscription/provider/base.rb', line 38

def async_exec(*method_names)
  method_names.each do |method_name|
    async_method_name = :"async_#{method_name}"

    class_eval do
      return warn((+"        Already async \#{method_name}\n      MSG\n\n      alias_method async_method_name, method_name\n\n      define_method(method_name) do |*args, **xargs|\n        if @mutex.owned?\n          send(async_method_name, *args, **xargs)\n        else\n          async_exec(async_method_name, *args, **xargs)\n        end\n      end\n    end\n  end\nend\n").squish) if method_defined?(async_method_name)

.newObject

Make sure that abstract classes cannot be instantiated

Raises:



28
29
30
31
32
33
34
# File 'lib/rails/graphql/subscription/provider/base.rb', line 28

def new(*, **)
  return super unless self.abstract

  raise StandardError, (+"    \#{name} is abstract and cannot be used as a subscription provider.\n  MSG\nend\n").squish

Instance Method Details

#accepts?(operation) ⇒ Boolean

Before even generating the item, check if the operation can be subscribed

Returns:

  • (Boolean)

Raises:

  • (NotImplementedError)


78
79
80
# File 'lib/rails/graphql/subscription/provider/base.rb', line 78

def accepts?(operation)
  raise NotImplementedError, +"#{self.class.name} does not implement accepts?"
end

#add(*subscriptions) ⇒ Object

Add one or more subscriptions to the provider

Raises:

  • (NotImplementedError)


83
84
85
# File 'lib/rails/graphql/subscription/provider/base.rb', line 83

def add(*subscriptions)
  raise NotImplementedError, +"#{self.class.name} does not implement add"
end

#shutdownObject

Use this method to remove variables that needs to be restarted when the provider is doing a refresh. Remember to keep the data in the store so that it can still recover and keep posting updates



73
74
# File 'lib/rails/graphql/subscription/provider/base.rb', line 73

def shutdown
end

#unsubscribed_payloadObject

Get the payload that should be used when unsubscribing



131
132
133
# File 'lib/rails/graphql/subscription/provider/base.rb', line 131

def unsubscribed_payload
  Request::Component::Operation::Subscription::UNSUBSCRIBED_PAYLOAD
end

#unsubscribing?(value) ⇒ Boolean

Check if the given value indicates that it is unsubscribing

Returns:

  • (Boolean)


136
137
138
# File 'lib/rails/graphql/subscription/provider/base.rb', line 136

def unsubscribing?(value)
  value == Request::Component::Operation::Subscription::UNSUBSCRIBED_RESULT
end