Skip to content

Commit 50d0e7f

Browse files
authored
Merge pull request #4401 from rmosolgo/field-extension-overhead-fix
Remove 'extended' hash from Field when it's unused
2 parents eca230c + bde5dbc commit 50d0e7f

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

benchmark/run.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,14 @@ module Baz
256256
end
257257

258258

259+
class ExampleExtension < GraphQL::Schema::FieldExtension
260+
end
261+
259262
class FooType < GraphQL::Schema::Object
260263
implements Baz
261-
field :id, ID, null: false
262-
field :int1, Integer, null: false
263-
field :int2, Integer, null: false
264+
field :id, ID, null: false, extensions: [ExampleExtension]
265+
field :int1, Integer, null: false, extensions: [ExampleExtension]
266+
field :int2, Integer, null: false, extensions: [ExampleExtension]
264267
field :string1, String, null: false do
265268
argument :arg1, String, required: false
266269
argument :arg2, String, required: false

lib/graphql/schema/field.rb

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,17 @@ def assert_satisfactory_implementation(receiver, method_name, ruby_kwargs)
810810
end
811811
end
812812

813+
class ExtendedState
814+
def initialize(args, object)
815+
@arguments = args
816+
@object = object
817+
@memos = nil
818+
@added_extras = nil
819+
end
820+
821+
attr_accessor :arguments, :object, :memos, :added_extras
822+
end
823+
813824
# Wrap execution with hooks.
814825
# Written iteratively to avoid big stack traces.
815826
# @return [Object] Whatever the
@@ -820,18 +831,18 @@ def with_extensions(obj, args, ctx)
820831
# This is a hack to get the _last_ value for extended obj and args,
821832
# in case one of the extensions doesn't `yield`.
822833
# (There's another implementation that uses multiple-return, but I'm wary of the perf cost of the extra arrays)
823-
extended = { args: args, obj: obj, memos: nil, added_extras: nil }
834+
extended = ExtendedState.new(args, obj)
824835
value = run_extensions_before_resolve(obj, args, ctx, extended) do |obj, args|
825-
if (added_extras = extended[:added_extras])
836+
if (added_extras = extended.added_extras)
826837
args = args.dup
827838
added_extras.each { |e| args.delete(e) }
828839
end
829840
yield(obj, args)
830841
end
831842

832-
extended_obj = extended[:obj]
833-
extended_args = extended[:args]
834-
memos = extended[:memos] || EMPTY_HASH
843+
extended_obj = extended.object
844+
extended_args = extended.arguments # rubocop:disable Development/ContextIsPassedCop
845+
memos = extended.memos || EMPTY_HASH
835846

836847
ctx.query.after_lazy(value) do |resolved_value|
837848
idx = 0
@@ -851,17 +862,17 @@ def run_extensions_before_resolve(obj, args, ctx, extended, idx: 0)
851862
if extension
852863
extension.resolve(object: obj, arguments: args, context: ctx) do |extended_obj, extended_args, memo|
853864
if memo
854-
memos = extended[:memos] ||= {}
865+
memos = extended.memos ||= {}
855866
memos[idx] = memo
856867
end
857868

858869
if (extras = extension.added_extras)
859-
ae = extended[:added_extras] ||= []
870+
ae = extended.added_extras ||= []
860871
ae.concat(extras)
861872
end
862873

863-
extended[:obj] = extended_obj
864-
extended[:args] = extended_args
874+
extended.object = extended_obj
875+
extended.arguments = extended_args
865876
run_extensions_before_resolve(extended_obj, extended_args, ctx, extended, idx: idx + 1) { |o, a| yield(o, a) }
866877
end
867878
else

0 commit comments

Comments
 (0)