Skip to content

Commit 7019ebc

Browse files
committed
Try a PORO for extension state
1 parent 593474d commit 7019ebc

File tree

2 files changed

+22
-25
lines changed

2 files changed

+22
-25
lines changed

benchmark/run.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,14 @@ module Baz
254254
end
255255

256256

257+
class ExampleExtension < GraphQL::Schema::FieldExtension
258+
end
259+
257260
class FooType < GraphQL::Schema::Object
258261
implements Baz
259-
field :id, ID, null: false
260-
field :int1, Integer, null: false
261-
field :int2, Integer, null: false
262+
field :id, ID, null: false, extensions: [ExampleExtension]
263+
field :int1, Integer, null: false, extensions: [ExampleExtension]
264+
field :int2, Integer, null: false, extensions: [ExampleExtension]
262265
field :string1, String, null: false do
263266
argument :arg1, String, required: false
264267
argument :arg2, String, required: false

lib/graphql/schema/field.rb

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,9 @@ def assert_satisfactory_implementation(receiver, method_name, ruby_kwargs)
807807
end
808808
end
809809

810+
class ExtendedState
811+
attr_accessor :arguments, :object, :memos, :added_extras
812+
end
810813
# Wrap execution with hooks.
811814
# Written iteratively to avoid big stack traces.
812815
# @return [Object] Whatever the
@@ -817,20 +820,20 @@ def with_extensions(obj, args, ctx)
817820
# This is a hack to get the _last_ value for extended obj and args,
818821
# in case one of the extensions doesn't `yield`.
819822
# (There's another implementation that uses multiple-return, but I'm wary of the perf cost of the extra arrays)
820-
extended = nil
821-
value = run_extensions_before_resolve(obj, args, ctx, extended) do |obj, args, ext_extended|
822-
# `ext_extended` may have been built up by the extensions:
823-
extended = ext_extended
824-
if extended && (added_extras = extended[:added_extras])
823+
extended = ExtendedState.new
824+
extended.arguments = args
825+
extended.object = obj
826+
value = run_extensions_before_resolve(obj, args, ctx, extended) do |obj, args|
827+
if (added_extras = extended.added_extras)
825828
args = args.dup
826829
added_extras.each { |e| args.delete(e) }
827830
end
828831
yield(obj, args)
829832
end
830833

831-
extended_obj = extended && extended.key?(:obj) ? extended[:obj] : obj
832-
extended_args = extended && extended.key?(:args) ? extended[:args] : args
833-
memos = extended && extended.key?(:memos) ? extended[:memos] : EMPTY_HASH
834+
extended_obj = extended.object
835+
extended_args = extended.arguments
836+
memos = extended.memos || EMPTY_HASH
834837

835838
ctx.schema.after_lazy(value) do |resolved_value|
836839
idx = 0
@@ -850,27 +853,18 @@ def run_extensions_before_resolve(obj, args, ctx, extended, idx: 0)
850853
if extension
851854
extension.resolve(object: obj, arguments: args, context: ctx) do |extended_obj, extended_args, memo|
852855
if memo
853-
extended ||= {}
854-
memos = extended[:memos] ||= {}
856+
memos = extended.memos ||= {}
855857
memos[idx] = memo
856858
end
857859

858860
if (extras = extension.added_extras)
859-
extended ||= {}
860-
ae = extended[:added_extras] ||= []
861+
ae = extended.added_extras ||= []
861862
ae.concat(extras)
862863
end
863864

864-
if !extended_obj.equal?(obj)
865-
extended ||= {}
866-
extended[:obj] = extended_obj
867-
end
868-
869-
if !extended_args.equal?(args)
870-
extended ||= {}
871-
extended[:args] = extended_args
872-
end
873-
run_extensions_before_resolve(extended_obj, extended_args, ctx, extended, idx: idx + 1) { |o, a, ext| yield(o, a, ext) }
865+
extended.object = extended_obj
866+
extended.arguments = extended_args
867+
run_extensions_before_resolve(extended_obj, extended_args, ctx, extended, idx: idx + 1) { |o, a| yield(o, a) }
874868
end
875869
else
876870
yield(obj, args, extended)

0 commit comments

Comments
 (0)