Class: GraphQL::Schema::Timeout
- Inherits:
-
Object
- Object
- GraphQL::Schema::Timeout
- Defined in:
- lib/graphql/schema/timeout.rb
Overview
This plugin will stop resolving new fields after max_seconds
have elapsed.
After the time has passed, any remaining fields will be nil
, with errors added
to the errors
key. Any already-resolved fields will be in the data
key, so
you’ll get a partial response.
You can subclass GraphQL::Schema::Timeout
and override the handle_timeout
method
to provide custom logic when a timeout error occurs.
Note that this will stop a query in between field resolutions, but
it doesn’t interrupt long-running resolve
functions. Be sure to use
timeout options for external connections. For more info, see
www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/
Defined Under Namespace
Classes: TimeoutError
Instance Attribute Summary collapse
-
#max_seconds ⇒ Object
readonly
Returns the value of attribute max_seconds.
Class Method Summary collapse
Instance Method Summary collapse
-
#handle_timeout(error, query) ⇒ Object
Invoked when a query times out.
-
#initialize(max_seconds:) ⇒ Timeout
constructor
A new instance of Timeout.
-
#trace(key, data) ⇒ Object
Constructor Details
#initialize(max_seconds:) ⇒ Timeout
Returns a new instance of Timeout
44 45 46 |
# File 'lib/graphql/schema/timeout.rb', line 44 def initialize(max_seconds:) @max_seconds = max_seconds end |
Instance Attribute Details
#max_seconds ⇒ Object (readonly)
Returns the value of attribute max_seconds
36 37 38 |
# File 'lib/graphql/schema/timeout.rb', line 36 def max_seconds @max_seconds end |
Class Method Details
.use(schema, **options) ⇒ Object
38 39 40 41 |
# File 'lib/graphql/schema/timeout.rb', line 38 def self.use(schema, **) tracer = new(**) schema.tracer(tracer) end |
Instance Method Details
#handle_timeout(error, query) ⇒ Object
Invoked when a query times out.
91 92 93 |
# File 'lib/graphql/schema/timeout.rb', line 91 def handle_timeout(error, query) # override to do something interesting end |
#trace(key, data) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/graphql/schema/timeout.rb', line 48 def trace(key, data) case key when 'execute_multiplex' timeout_state = { timeout_at: Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) + max_seconds * 1000, timed_out: false } data.fetch(:multiplex).queries.each do |query| query.context.namespace(self.class)[:state] = timeout_state end yield when 'execute_field', 'execute_field_lazy' query = data[:context] ? data.fetch(:context).query : data.fetch(:query) timeout_state = query.context.namespace(self.class).fetch(:state) if Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) > timeout_state.fetch(:timeout_at) error = if data[:context] context = data.fetch(:context) GraphQL::Schema::Timeout::TimeoutError.new(context.parent_type, context.field) else field = data.fetch(:field) GraphQL::Schema::Timeout::TimeoutError.new(field.owner, field) end # Only invoke the timeout callback for the first timeout unless timeout_state[:timed_out] timeout_state[:timed_out] = true handle_timeout(error, query) end error else yield end else yield end end |