Skip to content

Commit 5451eba

Browse files
committed
Add hooks for _lazy events
1 parent 9246b56 commit 5451eba

File tree

3 files changed

+71
-14
lines changed

3 files changed

+71
-14
lines changed

lib/graphql/execution/interpreter/runtime.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,8 +789,10 @@ def after_lazy(lazy_obj, field:, owner_object:, arguments:, ast_node:, result:,
789789
runtime_state.was_authorized_by_scope_items = was_authorized_by_scope_items
790790
# Wrap the execution of _this_ method with tracing,
791791
# but don't wrap the continuation below
792+
result = nil
792793
inner_obj = begin
793-
if trace
794+
result = if trace
795+
@current_trace.begin_execute_field(field, owner_object, arguments, query)
794796
@current_trace.execute_field_lazy(field: field, query: query, object: owner_object, arguments: arguments, ast_node: ast_node) do
795797
schema.sync_lazy(lazy_obj)
796798
end
@@ -805,6 +807,10 @@ def after_lazy(lazy_obj, field:, owner_object:, arguments:, ast_node:, result:,
805807
rescue GraphQL::ExecutionError => ex_err
806808
ex_err
807809
end
810+
ensure
811+
if trace
812+
@current_trace.end_execute_field(field, owner_object, arguments, query, result)
813+
end
808814
end
809815
yield(inner_obj, runtime_state)
810816
end
@@ -852,17 +858,18 @@ def resolve_type(type, value)
852858
resolved_type, resolved_value = @current_trace.resolve_type(query: query, type: type, object: value) do
853859
query.resolve_type(type, value)
854860
end
861+
@current_trace.end_resolve_type(type, value, context, resolved_type)
855862

856863
if lazy?(resolved_type)
857864
GraphQL::Execution::Lazy.new do
865+
@current_trace.begin_resolve_type(type, value, context)
858866
@current_trace.resolve_type_lazy(query: query, type: type, object: value) do
859867
rt = schema.sync_lazy(resolved_type)
860868
@current_trace.end_resolve_type(type, value, context, rt)
861869
rt
862870
end
863871
end
864872
else
865-
@current_trace.end_resolve_type(type, value, context, resolved_type)
866873
[resolved_type, resolved_value]
867874
end
868875
end

lib/graphql/schema/object.rb

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,29 +66,35 @@ def wrap(object, context)
6666
# @return [GraphQL::Schema::Object, GraphQL::Execution::Lazy]
6767
# @raise [GraphQL::UnauthorizedError] if the user-provided hook returns `false`
6868
def authorized_new(object, context)
69-
maybe_lazy_auth_val = context.query.current_trace.authorized(query: context.query, type: self, object: object) do
70-
begin
71-
context.query.current_trace.begin_authorized(self, object, context)
72-
authorized?(object, context)
73-
rescue GraphQL::UnauthorizedError => err
74-
context.schema.unauthorized_object(err)
75-
rescue StandardError => err
76-
context.query.handle_or_reraise(err)
69+
context.query.current_trace.begin_authorized(self, object, context)
70+
begin
71+
maybe_lazy_auth_val = context.query.current_trace.authorized(query: context.query, type: self, object: object) do
72+
begin
73+
authorized?(object, context)
74+
rescue GraphQL::UnauthorizedError => err
75+
context.schema.unauthorized_object(err)
76+
rescue StandardError => err
77+
context.query.handle_or_reraise(err)
78+
end
7779
end
80+
ensure
81+
context.query.current_trace.end_authorized(self, object, context, maybe_lazy_auth_val)
7882
end
7983

8084
auth_val = if context.schema.lazy?(maybe_lazy_auth_val)
8185
GraphQL::Execution::Lazy.new do
86+
context.query.current_trace.begin_authorized(self, object, context)
8287
context.query.current_trace.authorized_lazy(query: context.query, type: self, object: object) do
83-
context.schema.sync_lazy(maybe_lazy_auth_val)
88+
res = context.schema.sync_lazy(maybe_lazy_auth_val)
89+
context.query.current_trace.end_authorized(self, object, context, res)
90+
res
8491
end
8592
end
8693
else
8794
maybe_lazy_auth_val
8895
end
8996

9097
context.query.after_lazy(auth_val) do |is_authorized|
91-
context.query.current_trace.end_authorized(self, object, context, is_authorized)
9298
if is_authorized
9399
self.new(object, context)
94100
else

spec/graphql/tracing/new_relic_trace_spec.rb

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@ module Nameable
2323
field :name, String
2424

2525
def self.resolve_type(abs_type, ctx)
26-
Other
26+
ctx[:lazy] ? -> { Other } : Other
2727
end
2828
end
2929
class Other < GraphQL::Schema::Object
3030
implements Nameable
31+
def self.authorized?(obj, ctx)
32+
ctx[:lazy] ? -> { true } : true
33+
end
3134
field :name, String, fallback_value: "other"
3235
end
3336

@@ -47,6 +50,8 @@ def other
4750
end
4851

4952
field :nameable, Nameable, fallback_value: :nameable
53+
54+
field :lazy_nameable, Nameable, fallback_value: -> { :nameable }
5055
end
5156

5257
class SchemaWithoutTransactionName < GraphQL::Schema
@@ -58,7 +63,7 @@ def self.object_from_id(_id, _ctx)
5863
:thing
5964
end
6065

61-
def self.resolve_type(_type, _obj, _ctx)
66+
def self.resolve_type(_type, _obj, ctx)
6267
Thing
6368
end
6469
end
@@ -67,6 +72,7 @@ class SchemaWithTransactionName < GraphQL::Schema
6772
query(Query)
6873
trace_with(GraphQL::Tracing::NewRelicTrace, set_transaction_name: true)
6974
use GraphQL::Dataloader
75+
lazy_resolve(Proc, :call)
7076
end
7177

7278
class SchemaWithScalarTrace < GraphQL::Schema
@@ -197,4 +203,42 @@ class SchemaWithoutAuthorizedOrResolveType < GraphQL::Schema
197203
assert_equal ["An operation name is required"], res["errors"].map { |e| e["message"] }
198204
assert_equal ["GraphQL/query.anonymous"], NewRelic::TRANSACTION_NAMES
199205
end
206+
207+
it "handles lazies" do
208+
NewRelicTraceTest::SchemaWithTransactionName.execute("{ lazyNameable { name } }", context: { lazy: true })
209+
expected_steps = [
210+
"GraphQL/parse",
211+
"FINISH GraphQL/parse",
212+
"GraphQL/execute",
213+
"GraphQL/analyze",
214+
"GraphQL/validate",
215+
"FINISH GraphQL/validate",
216+
"FINISH GraphQL/analyze",
217+
"GraphQL/Authorized/Query",
218+
"FINISH GraphQL/Authorized/Query",
219+
# Eager:
220+
"GraphQL/Query/lazyNameable",
221+
"FINISH GraphQL/Query/lazyNameable",
222+
# Lazy:
223+
"GraphQL/Query/lazyNameable",
224+
"FINISH GraphQL/Query/lazyNameable",
225+
226+
# Eager/lazy:
227+
"GraphQL/ResolveType/Nameable",
228+
"FINISH GraphQL/ResolveType/Nameable",
229+
"GraphQL/ResolveType/Nameable",
230+
"FINISH GraphQL/ResolveType/Nameable",
231+
232+
# Eager/lazy:
233+
"GraphQL/Authorized/Other",
234+
"FINISH GraphQL/Authorized/Other",
235+
"GraphQL/Authorized/Other",
236+
"FINISH GraphQL/Authorized/Other",
237+
238+
"GraphQL/Other/name",
239+
"FINISH GraphQL/Other/name",
240+
"FINISH GraphQL/execute",
241+
]
242+
assert_equal expected_steps, NewRelic::EXECUTION_SCOPES
243+
end
200244
end

0 commit comments

Comments
 (0)