Skip to content

Commit

Permalink
Add LegacyTrace for backwards compat
Browse files Browse the repository at this point in the history
  • Loading branch information
rmosolgo committed Feb 15, 2023
1 parent 13f90ac commit 3436101
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 10 deletions.
12 changes: 9 additions & 3 deletions lib/graphql/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,18 @@ def initialize(schema, query_string = nil, query: nil, document: nil, context: n
@fragments = nil
@operations = nil
@validate = validate
@tracers = schema.tracers + (context ? context.fetch(:tracers, []) : [])
context_tracers = (context ? context.fetch(:tracers, []) : [])
# Support `ctx[:backtrace] = true` for wrapping backtraces
if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
@tracers << GraphQL::Backtrace::Tracer
context_tracers += GraphQL::Backtrace::Tracer
end

if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::LegacyTrace)
raise ArgumentError, "context[:tracers] and context[:backtrace] are not supported without `tracer_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
end

@tracers = schema.tracers + context_tracers

@analysis_errors = []
if variables.is_a?(String)
raise ArgumentError, "Query variables should be a Hash, not a String. Try JSON.parse to prepare variables."
Expand Down Expand Up @@ -159,7 +165,7 @@ def interpreter?

# @return [GraphQL::Tracing::Trace]
def current_trace
multiplex.current_trace
@current_trace ||= multiplex ? multiplex.current_trace : schema.trace_class.new
end

def subscription_update?
Expand Down
6 changes: 6 additions & 0 deletions lib/graphql/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,12 @@ def default_directives
end

def tracer(new_tracer)
if defined?(@trace_class) && !(@trace_class < GraphQL::Tracing::LegacyTrace)
raise ArgumentError, "Can't add tracer after configuring a `trace_class`, use GraphQL::Tracing::LegacyTrace to merge legacy tracers into a trace class instead."
elsif !defined?(@trace_class)
@trace_class = Class.new(GraphQL::Tracing::LegacyTrace)
end

own_tracers << new_tracer
end

Expand Down
79 changes: 72 additions & 7 deletions lib/graphql/tracing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@ module GraphQL
#
module Tracing
class Trace
def initialize
class << self
attr_accessor :schema
end

def lex(query_string:)
yield
end
# TODO
# def lex(query_string:)
# yield
# end

def parse(query_string:)
yield
end
# def parse(query_string:)
# yield
# end

def validate(query:, validate:)
yield
Expand Down Expand Up @@ -114,6 +116,69 @@ def resolve_type_lazy(query:, type:, object:)
yield
end
end

class LegacyTrace < Trace
def initialize
end

# TODO: These are not migrated yet
# def lex(query_string:)
# yield
# end

# def parse(query_string:)
# yield
# end

def validate(query:, validate:, &block)
query.trace("validate", { validate: validate, query: query }, &block)
end

def analyze_multiplex(multiplex:, &block)
multiplex.trace("analyze_multiplex", { multiplex: multiplex }, &block)
end

def analyze_query(query:, &block)
query.trace("analyze_query", { query: query }, &block)
end

def execute_multiplex(multiplex:, &block)
multiplex.trace("execute_multiplex", { multiplex: multiplex }, &block)
end

def execute_query(query:, &block)
query.trace("execute_query", { query: query }, &block)
end

def execute_query_lazy(query:, &block)
query.trace("execute_query_lazy", { multiplex: query.multiplex, query: query }, &block)
end

def execute_field(field:, query:, ast_node:, arguments:, object:, &block)
query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }, &block)
end

def execute_field_lazy(field:, query:, ast_node:, arguments:, object:, &block)
query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }, &block)
end

def authorized(query:, type:, object:, &block)
query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end

def authorized_lazy(query:, type:, object:, &block)
query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end

def resolve_type(query:, type:, object:, &block)
query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end

def resolve_type_lazy(query:, type:, object:, &block)
query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }, &block)
end
end

# Objects may include traceable to gain a `.trace(...)` method.
# The object must have a `@tracers` ivar of type `Array<<#trace(k, d, &b)>>`.
# @api private
Expand Down
1 change: 1 addition & 0 deletions spec/support/dummy/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ class Schema < GraphQL::Schema
subscription Subscription
max_depth 5
orphan_types Honey, Beverage
trace_class GraphQL::Tracing::LegacyTrace

rescue_from(NoSuchDairyError) { |err| raise GraphQL::ExecutionError, err.message }

Expand Down

0 comments on commit 3436101

Please sign in to comment.