Class: GraphQL::Schema::TimeoutMiddleware Private

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql/schema/timeout_middleware.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

This middleware 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 provide a block which will be called with any timeout errors that occur.

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/

Examples:

Stop resolving fields after 2 seconds

MySchema.middleware << GraphQL::Schema::TimeoutMiddleware.new(max_seconds: 2)

Notifying Bugsnag on a timeout

MySchema.middleware << GraphQL::Schema::TimeoutMiddleware(max_seconds: 1.5) do |timeout_error, query|
 Bugsnag.notify(timeout_error, {query_string: query_ctx.query.query_string})
end

Defined Under Namespace

Classes: TimeoutError, TimeoutQueryProxy

Instance Method Summary collapse

Constructor Details

#initialize(max_seconds:, context_key: nil, &block) ⇒ TimeoutMiddleware

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of TimeoutMiddleware

Parameters:

  • max_seconds (Numeric)

    how many seconds the query should be allowed to resolve new fields



28
29
30
31
32
33
34
# File 'lib/graphql/schema/timeout_middleware.rb', line 28

def initialize(max_seconds:, context_key: nil, &block)
  @max_seconds = max_seconds
  if context_key
    warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
  end
  @error_handler = block
end

Instance Method Details

#call(parent_type, parent_object, field_definition, field_args, query_context) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



36
37
38
39
40
41
42
43
44
45
# File 'lib/graphql/schema/timeout_middleware.rb', line 36

def call(parent_type, parent_object, field_definition, field_args, query_context)
  ns = query_context.namespace(TimeoutMiddleware)
  timeout_at = ns[:timeout_at] ||= Time.now + @max_seconds

  if timeout_at < Time.now
    on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
  else
    yield
  end
end

#on_timeout(parent_type, parent_object, field_definition, field_args, field_context) ⇒ GraphQL::Schema::TimeoutMiddleware::TimeoutError

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This is called when a field would be resolved, except that we’re over the time limit.

Returns:



49
50
51
52
53
54
55
56
# File 'lib/graphql/schema/timeout_middleware.rb', line 49

def on_timeout(parent_type, parent_object, field_definition, field_args, field_context)
  err = GraphQL::Schema::TimeoutMiddleware::TimeoutError.new(parent_type, field_definition)
  if @error_handler
    query_proxy = TimeoutQueryProxy.new(field_context.query, field_context)
    @error_handler.call(err, query_proxy)
  end
  err
end