Skip to content

Commit d147ee4

Browse files
committed
Store represented_value in the result objects
1 parent 9a21dc9 commit d147ee4

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

lib/graphql/execution/interpreter/runtime.rb

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ def initialize
2222
end
2323

2424
module GraphQLResult
25-
def initialize(result_name, parent_result, is_non_null_in_parent)
25+
# FIXME: storing `represented_value` here holds onto a lot of objects, keeping them from GCing and increasing peak memory.
26+
# ... but the value is only needed for lists with skippable items.
27+
# Maybe we can set to `nil` unless we know this object is a skippable list item
28+
# (i.e. a direct child of a list with `skip_items_on_raise: true`)
29+
def initialize(result_name, parent_result, is_non_null_in_parent, represented_value)
2630
@graphql_parent = parent_result
2731
if parent_result && parent_result.graphql_dead
2832
@graphql_dead = true
@@ -31,6 +35,7 @@ def initialize(result_name, parent_result, is_non_null_in_parent)
3135
@graphql_is_non_null_in_parent = is_non_null_in_parent
3236
# Jump through some hoops to avoid creating this duplicate storage if at all possible.
3337
@graphql_metadata = nil
38+
@represented_value = represented_value
3439
end
3540

3641
def path
@@ -43,7 +48,7 @@ def build_path(path_array)
4348
end
4449

4550
attr_accessor :graphql_dead
46-
attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent
51+
attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent, :represented_value
4752

4853
# True when this result is a List that was marked `skip_items_on_raise: true`.
4954
# Descendants of this result will have `can_be_skipped?` be true.
@@ -63,7 +68,7 @@ def can_be_skipped?
6368
end
6469

6570
class GraphQLResultHash
66-
def initialize(_result_name, _parent_result, _is_non_null_in_parent)
71+
def initialize(_result_name, _parent_result, _is_non_null_in_parent, _represented_value)
6772
super
6873
@graphql_result_data = {}
6974
end
@@ -151,7 +156,7 @@ def merge_into(into_result)
151156
class GraphQLResultArray
152157
include GraphQLResult
153158

154-
def initialize(_result_name, _parent_result, _is_non_null_in_parent)
159+
def initialize(_result_name, _parent_result, _is_non_null_in_parent, _represented_value)
155160
super
156161
@graphql_result_data = []
157162
end
@@ -211,7 +216,7 @@ def initialize(query:, lazies_at_depth:)
211216
@lazies_at_depth = lazies_at_depth
212217
@schema = query.schema
213218
@context = query.context
214-
@response = GraphQLResultHash.new(nil, nil, false)
219+
@response = GraphQLResultHash.new(nil, nil, false, query.root_value)
215220
# Identify runtime directives by checking which of this schema's directives have overridden `def self.resolve`
216221
@runtime_directive_names = []
217222
noop_resolve_owner = GraphQL::Schema::Directive.singleton_class
@@ -278,7 +283,7 @@ def run_eager
278283
# directly evaluated and the results can be written right into the main response hash.
279284
tap_or_each(gathered_selections) do |selections, is_selection_array|
280285
if is_selection_array
281-
selection_response = GraphQLResultHash.new(nil, nil, false)
286+
selection_response = GraphQLResultHash.new(nil, nil, false, query.root_value)
282287
final_response = @response
283288
else
284289
selection_response = @response
@@ -835,7 +840,7 @@ def continue_field(value, owner_type, field, current_type, ast_node, next_select
835840
after_lazy(object_proxy, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result) do |inner_object|
836841
continue_value = continue_value(inner_object, owner_type, field, is_non_null, ast_node, result_name, selection_result)
837842
if HALT != continue_value
838-
response_hash = GraphQLResultHash.new(result_name, selection_result, is_non_null)
843+
response_hash = GraphQLResultHash.new(result_name, selection_result, is_non_null, continue_value)
839844
set_result(selection_result, result_name, response_hash, true, is_non_null)
840845
gathered_selections = gather_selections(continue_value, current_type, next_selections)
841846
# There are two possibilities for `gathered_selections`:
@@ -848,7 +853,7 @@ def continue_field(value, owner_type, field, current_type, ast_node, next_select
848853
# (Technically, it's possible that one of those entries _doesn't_ require isolation.)
849854
tap_or_each(gathered_selections) do |selections, is_selection_array|
850855
if is_selection_array
851-
this_result = GraphQLResultHash.new(result_name, selection_result, is_non_null)
856+
this_result = GraphQLResultHash.new(result_name, selection_result, is_non_null, continue_value)
852857
final_result = response_hash
853858
else
854859
this_result = response_hash
@@ -885,7 +890,7 @@ def continue_field(value, owner_type, field, current_type, ast_node, next_select
885890
# This is true for objects, unions, and interfaces
886891
use_dataloader_job = !inner_type.unwrap.kind.input?
887892
inner_type_non_null = inner_type.non_null?
888-
response_list = GraphQLResultArray.new(result_name, selection_result, is_non_null)
893+
response_list = GraphQLResultArray.new(result_name, selection_result, is_non_null, value)
889894
response_list.graphql_skip_list_items_that_raise = current_type.skip_nodes_on_raise?
890895
set_result(selection_result, result_name, response_list, true, is_non_null)
891896
idx = nil

0 commit comments

Comments
 (0)