1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
# frozen_string_literal: true
module GraphQL
module Execution
# Execute multiple queries under the same multiplex "umbrella".
# They can share a batching context and reduce redundant database hits.
#
# The flow is:
#
# - Multiplex instrumentation setup
# - Query instrumentation setup
# - Analyze the multiplex + each query
# - Begin each query
# - Resolve lazy values, breadth-first across all queries
# - Finish each query (eg, get errors)
# - Query instrumentation teardown
# - Multiplex instrumentation teardown
#
# If one query raises an application error, all queries will be in undefined states.
#
# Validation errors and {GraphQL::ExecutionError}s are handled in isolation:
# one of these errors in one query will not affect the other queries.
#
# @see {Schema#multiplex} for public API
# @api private
class Multiplex
include Tracing::Traceable
attr_reader :context, :queries, :schema, :max_complexity, :dataloader, :current_trace
def initialize(schema:, queries:, context:, max_complexity:)
@schema = schema
@queries = queries
@queries.each { |q| q.multiplex = self }
@context = context
@current_trace = @context[:trace] || schema.new_trace(multiplex: self)
@dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
@tracers = schema.tracers + (context[:tracers] || [])
# Support `context: {backtrace: true}`
if context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
@tracers << GraphQL::Backtrace::Tracer
end
@max_complexity = max_complexity
end
end
end
end
|