Skip to content

Commit 4c297b0

Browse files
authored
Merge pull request #4487 from rmosolgo/better-trace-compat
Fix tracer compatibility with inheritance
2 parents 3f5e22a + 42f8d7c commit 4c297b0

File tree

7 files changed

+60
-15
lines changed

7 files changed

+60
-15
lines changed

lib/graphql/query.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,16 @@ def initialize(schema, query_string = nil, query: nil, document: nil, context: n
102102

103103
# Support `ctx[:backtrace] = true` for wrapping backtraces
104104
if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
105-
if schema.trace_class <= GraphQL::Tracing::LegacyTrace
105+
if schema.trace_class <= GraphQL::Tracing::CallLegacyTracers
106106
context_tracers += [GraphQL::Backtrace::Tracer]
107107
@tracers << GraphQL::Backtrace::Tracer
108108
elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
109109
raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
110110
end
111111
end
112112

113-
if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::LegacyTrace)
114-
raise ArgumentError, "context[:tracers] are not supported without `trace_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
113+
if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
114+
raise ArgumentError, "context[:tracers] are not supported without `trace_with(GraphQL::Tracing::CallLegacyTracers)` in the schema configuration, please add it."
115115
end
116116

117117

lib/graphql/schema.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -961,10 +961,8 @@ def default_directives
961961
end
962962

963963
def tracer(new_tracer)
964-
if defined?(@trace_modes) && !(trace_class_for(:default) < GraphQL::Tracing::LegacyTrace)
965-
raise ArgumentError, "Can't add tracer after configuring a `trace_class`, use GraphQL::Tracing::LegacyTrace to merge legacy tracers into a trace class instead."
966-
else
967-
trace_mode(:default, Class.new(GraphQL::Tracing::LegacyTrace))
964+
if !(trace_class_for(:default) < GraphQL::Tracing::CallLegacyTracers)
965+
trace_with(GraphQL::Tracing::CallLegacyTracers)
968966
end
969967

970968
own_tracers << new_tracer

lib/graphql/tracing/legacy_trace.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Tracing
44
# This trace class calls legacy-style tracer with payload hashes.
55
# New-style `trace_with` modules significantly reduce the overhead of tracing,
66
# but that advantage is lost when legacy-style tracers are also used (since the payload hashes are still constructed).
7-
class LegacyTrace < Trace
7+
module CallLegacyTracers
88
def lex(query_string:)
99
(@multiplex || @query).trace("lex", { query_string: query_string }) { super }
1010
end
@@ -61,5 +61,9 @@ def resolve_type_lazy(query:, type:, object:)
6161
query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
6262
end
6363
end
64+
65+
class LegacyTrace < Trace
66+
include CallLegacyTracers
67+
end
6468
end
6569
end

spec/graphql/backtrace_spec.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@ def self.after_query(query)
212212
it "raises original exception instead of a TracedError when error does not occur during resolving" do
213213
instrumentation_schema = Class.new(schema) do
214214
instrument(:query, ErrorInstrumentation)
215-
trace_class(GraphQL::Tracing::LegacyTrace)
216215
end
217216

218217
assert_raises(RuntimeError) {

spec/graphql/schema_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ class CustomSubscriptions < GraphQL::Subscriptions::ActionCableSubscriptions
151151
assert_equal base_schema.multiplex_analyzers + [multiplex_analyzer], schema.multiplex_analyzers
152152
assert_equal [GraphQL::Backtrace, GraphQL::Subscriptions::ActionCableSubscriptions, CustomSubscriptions], schema.plugins.map(&:first)
153153
assert_equal [GraphQL::Tracing::DataDogTracing], base_schema.tracers
154-
assert_includes base_schema.trace_class.ancestors, GraphQL::Tracing::LegacyTrace
154+
assert_includes base_schema.trace_class.ancestors, GraphQL::Tracing::CallLegacyTracers
155155
assert_equal [GraphQL::Tracing::DataDogTracing, GraphQL::Tracing::NewRelicTracing], schema.tracers
156-
assert_includes schema.trace_class.ancestors, GraphQL::Tracing::LegacyTrace
156+
assert_includes schema.trace_class.ancestors, GraphQL::Tracing::CallLegacyTracers
157157

158158

159159
assert_instance_of CustomSubscriptions, schema.subscriptions

spec/graphql/tracing/legacy_trace_spec.rb

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
custom_tracer = Module.new do
77
def self.trace(key, data)
88
if key == "execute_query"
9-
data[:query].context[:trace_ran] = true
9+
data[:query].context[:tracer_ran] = true
1010
end
1111
yield
1212
end
@@ -29,9 +29,53 @@ def int
2929

3030

3131
res1 = parent_schema.execute("{ int }")
32-
assert_equal true, res1.context[:trace_ran]
32+
assert_equal true, res1.context[:tracer_ran]
3333

3434
res2 = child_schema.execute("{ int }")
35-
assert_equal true, res2.context[:trace_ran]
35+
assert_equal true, res2.context[:tracer_ran]
36+
end
37+
38+
it "Works with new trace modules in the parent class" do
39+
custom_tracer = Module.new do
40+
def self.trace(key, data)
41+
if key == "execute_query"
42+
data[:query].context[:tracer_ran] = true
43+
end
44+
yield
45+
end
46+
end
47+
48+
custom_trace_module = Module.new do
49+
def execute_query(query:)
50+
query.context[:trace_module_ran] = true
51+
end
52+
end
53+
54+
55+
query_type = Class.new(GraphQL::Schema::Object) do
56+
graphql_name("Query")
57+
field :int, Integer
58+
def int
59+
4
60+
end
61+
end
62+
63+
parent_schema = Class.new(GraphQL::Schema) do
64+
query(query_type)
65+
trace_with(custom_trace_module)
66+
end
67+
68+
child_schema = Class.new(parent_schema) do
69+
tracer(custom_tracer)
70+
end
71+
72+
73+
res1 = parent_schema.execute("{ int }")
74+
assert_equal true, res1.context[:trace_module_ran]
75+
assert_nil res1.context[:tracer_ran]
76+
77+
res2 = child_schema.execute("{ int }")
78+
assert_equal true, res2.context[:trace_module_ran]
79+
assert_equal true, res2.context[:tracer_ran]
3680
end
3781
end

spec/support/dummy/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ class Schema < GraphQL::Schema
517517
subscription Subscription
518518
max_depth 5
519519
orphan_types Honey, Beverage
520-
trace_class GraphQL::Tracing::LegacyTrace
520+
trace_with GraphQL::Tracing::CallLegacyTracers
521521

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

0 commit comments

Comments
 (0)