graphql 2.6.3 → 2.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9f149d55f546745aa90807691e6ad3bc31528f341e6055ffc2146a06df033175
|
|
4
|
+
data.tar.gz: 4c153cc3bdd4ec208dbcf4e98de46834e8abd19bd338d553034245a452b84546
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6f663ca7de9f4943173238e3bde41d06d9cd36cf1fbdeabffd8096e19bdd00fd62ec1a6d4aa4f3938297e94d090d0b1f1013931def778c77f7519ae598bcd431
|
|
7
|
+
data.tar.gz: 2d76f7eff773781453598832e119c16f589ac8f8644cba892fa137fbaf4aa29545eed4f1606f731192dce4af1ff065101cf00a436eb257da4864a687e4b644ac
|
|
@@ -29,14 +29,14 @@ module GraphQL
|
|
|
29
29
|
future_complexity
|
|
30
30
|
end
|
|
31
31
|
when nil
|
|
32
|
-
subject.logger.warn <<~
|
|
32
|
+
subject.logger.warn <<~MESSAGE
|
|
33
33
|
GraphQL-Ruby's complexity cost system is getting some "breaking fixes" in a future version. See the migration notes at https://graphql-ruby.org/api-doc/#{GraphQL::VERSION}/GraphQL/Schema.html#complexity_cost_calculation_mode_for-class_method
|
|
34
34
|
|
|
35
35
|
To opt into the future behavior, configure your schema (#{subject.schema.name ? subject.schema.name : subject.schema.ancestors}) with:
|
|
36
36
|
|
|
37
37
|
complexity_cost_calculation_mode(:future) # or `:legacy`, `:compare`
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
MESSAGE
|
|
40
40
|
max_possible_complexity(mode: :legacy)
|
|
41
41
|
else
|
|
42
42
|
raise ArgumentError, "Expected `:future`, `:legacy`, `:compare`, or `nil` from `#{query.schema}.complexity_cost_calculation_mode_for` but got: #{query.schema.complexity_cost_calculation_mode.inspect}"
|
|
@@ -1,86 +1,234 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module GraphQL
|
|
3
4
|
class Dataloader
|
|
4
5
|
class AsyncDataloader < Dataloader
|
|
5
6
|
def yield(source = Fiber[:__graphql_current_dataloader_source])
|
|
6
|
-
|
|
7
|
+
run = Fiber[:__graphql_async_dataloader_run]
|
|
8
|
+
trace = run.trace
|
|
7
9
|
trace&.dataloader_fiber_yield(source)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
task = Async::Task.current
|
|
11
|
+
run.finished_tasks.push(task)
|
|
12
|
+
condition = Fiber[:__graphql_async_dataloader_condition]
|
|
13
|
+
condition.wait
|
|
14
|
+
run.started_tasks.push(task)
|
|
13
15
|
trace&.dataloader_fiber_resume(source)
|
|
14
16
|
nil
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
trace
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
next_source_tasks = []
|
|
24
|
-
first_pass = true
|
|
25
|
-
sources_condition = Async::Condition.new
|
|
26
|
-
manager = spawn_fiber do
|
|
27
|
-
trace&.begin_dataloader(self)
|
|
28
|
-
while first_pass || !job_fibers.empty?
|
|
29
|
-
first_pass = false
|
|
30
|
-
fiber_vars = get_fiber_variables
|
|
19
|
+
class Run
|
|
20
|
+
def initialize(root_task, trace, total_fiber_limit, jobs_fiber_limit)
|
|
21
|
+
@root_task = root_task
|
|
22
|
+
@trace = trace
|
|
23
|
+
@total_fiber_limit = total_fiber_limit
|
|
24
|
+
@jobs_fiber_limit = jobs_fiber_limit
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
@finished_tasks = nil
|
|
27
|
+
@started_tasks = nil
|
|
28
|
+
@started_count_task = nil
|
|
29
|
+
@finished_count_task = nil
|
|
30
|
+
@finished_all_tasks = nil
|
|
31
|
+
@finished_first_pass = nil
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
@snoozed_jobs_condition = Async::Condition.new
|
|
34
|
+
@snoozed_sources_condition = Async::Condition.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
attr_reader :root_task, :trace, :jobs_fiber_limit, :total_fiber_limit, :finished_tasks, :started_tasks, :snoozed_jobs_condition, :snoozed_sources_condition
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def jobs_bandwidth?
|
|
41
|
+
running_count < jobs_fiber_limit
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def allowed_sources_tasks
|
|
45
|
+
within_limit = total_fiber_limit - running_count
|
|
46
|
+
if within_limit < 1
|
|
47
|
+
1
|
|
48
|
+
else
|
|
49
|
+
within_limit
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def close_queues
|
|
54
|
+
@finished_tasks.close
|
|
55
|
+
@finished_count_task.cancel
|
|
56
|
+
|
|
57
|
+
@started_tasks.close
|
|
58
|
+
@started_count_task.cancel
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def running_count
|
|
62
|
+
@snoozed_jobs_condition.instance_variable_get(:@ready).num_waiting +
|
|
63
|
+
@snoozed_sources_condition.instance_variable_get(:@ready).num_waiting +
|
|
64
|
+
@started_count +
|
|
65
|
+
@started_tasks.size -
|
|
66
|
+
@finished_count
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def wait_for_queues
|
|
70
|
+
if !@finished_first_pass.resolved?
|
|
71
|
+
@finished_first_pass.resolve(true)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
@finished_all_tasks.wait
|
|
75
|
+
@finished_all_tasks = Async::Promise.new
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def new_queues
|
|
79
|
+
@finished_tasks = Async::Queue.new
|
|
80
|
+
@finished_count = 0
|
|
81
|
+
@started_tasks = Async::Queue.new
|
|
82
|
+
@started_count = 0
|
|
83
|
+
@finished_first_pass = Async::Promise.new
|
|
84
|
+
@finished_all_tasks = Async::Promise.new
|
|
85
|
+
|
|
86
|
+
@started_count_task = @root_task.async do
|
|
87
|
+
@finished_first_pass.wait
|
|
88
|
+
while _t = @started_tasks.wait
|
|
89
|
+
@started_count += 1
|
|
90
|
+
if @finished_count == @started_count
|
|
91
|
+
@finished_all_tasks.resolve(true)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
@finished_count_task = @root_task.async do
|
|
97
|
+
while t_or_err = @finished_tasks.wait
|
|
98
|
+
if t_or_err.is_a?(StandardError)
|
|
99
|
+
@finished_all_tasks.reject(t_or_err)
|
|
100
|
+
else
|
|
101
|
+
@finished_count +=1
|
|
102
|
+
if @finished_count == @started_count
|
|
103
|
+
@finished_all_tasks.resolve(true)
|
|
42
104
|
end
|
|
43
|
-
sources_condition.signal
|
|
44
|
-
source_tasks.concat(next_source_tasks)
|
|
45
|
-
next_source_tasks.clear
|
|
46
105
|
end
|
|
47
106
|
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def running?
|
|
111
|
+
@snoozed_jobs_condition.waiting? || @snoozed_sources_condition.waiting?
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def run(trace_query_lazy: nil)
|
|
116
|
+
trace = Fiber[:__graphql_current_multiplex]&.current_trace
|
|
117
|
+
jobs_fiber_limit, total_fiber_limit = calculate_fiber_limit
|
|
118
|
+
first_pass = true
|
|
119
|
+
trace&.begin_dataloader(self)
|
|
120
|
+
fiber_vars = get_fiber_variables
|
|
121
|
+
raised_error = nil
|
|
122
|
+
Sync do |root_task|
|
|
123
|
+
run = Run.new(root_task, trace, total_fiber_limit, jobs_fiber_limit)
|
|
124
|
+
set_fiber_variables(fiber_vars)
|
|
125
|
+
|
|
126
|
+
while first_pass || run.running? || !@pending_jobs.empty?
|
|
127
|
+
first_pass = false
|
|
128
|
+
run_pending_steps(run)
|
|
129
|
+
run_sources(run)
|
|
48
130
|
|
|
49
131
|
if !@lazies_at_depth.empty?
|
|
50
132
|
with_trace_query_lazy(trace_query_lazy) do
|
|
51
|
-
run_next_pending_lazies(
|
|
52
|
-
run_pending_steps(
|
|
133
|
+
run_next_pending_lazies(run)
|
|
134
|
+
run_pending_steps(run)
|
|
53
135
|
end
|
|
54
136
|
end
|
|
55
137
|
end
|
|
56
|
-
|
|
138
|
+
rescue StandardError => err
|
|
139
|
+
raised_error = err
|
|
140
|
+
root_task.cancel
|
|
57
141
|
end
|
|
58
142
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
raise "Invariant: Manager didn't terminate successfully: #{manager}"
|
|
143
|
+
if raised_error
|
|
144
|
+
raise raised_error
|
|
62
145
|
end
|
|
63
|
-
|
|
146
|
+
trace&.end_dataloader(self)
|
|
64
147
|
rescue UncaughtThrowError => e
|
|
65
148
|
throw e.tag, e.value
|
|
66
149
|
end
|
|
67
150
|
|
|
68
151
|
private
|
|
69
152
|
|
|
70
|
-
def run_pending_steps(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
153
|
+
def run_pending_steps(run)
|
|
154
|
+
run.new_queues
|
|
155
|
+
|
|
156
|
+
if (unsnoozed = run.snoozed_jobs_condition.waiting?)
|
|
157
|
+
run.snoozed_jobs_condition.signal
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
while (!@pending_jobs.empty? && (has_limit = run.jobs_bandwidth?)) || (unsnoozed)
|
|
161
|
+
unsnoozed = false
|
|
162
|
+
if has_limit
|
|
163
|
+
spawn_job_task(run)
|
|
164
|
+
end
|
|
165
|
+
run.wait_for_queues
|
|
166
|
+
end
|
|
167
|
+
ensure
|
|
168
|
+
run.close_queues
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def spawn_job_task(run)
|
|
172
|
+
if !@pending_jobs.empty?
|
|
173
|
+
fiber_vars = get_fiber_variables
|
|
174
|
+
run.root_task.async do |task|
|
|
175
|
+
run.trace&.dataloader_spawn_execution_fiber(@pending_jobs)
|
|
176
|
+
Fiber[:__graphql_async_dataloader_run] = run
|
|
177
|
+
Fiber[:__graphql_async_dataloader_condition] = run.snoozed_jobs_condition
|
|
178
|
+
set_fiber_variables(fiber_vars)
|
|
179
|
+
run.started_tasks.push(task)
|
|
180
|
+
while job = @pending_jobs.shift
|
|
181
|
+
job.call
|
|
76
182
|
end
|
|
183
|
+
ensure
|
|
184
|
+
cleanup_fiber
|
|
185
|
+
run.finished_tasks.push($! || task)
|
|
186
|
+
run.trace&.dataloader_fiber_exit
|
|
77
187
|
end
|
|
78
188
|
end
|
|
79
|
-
job_fibers.concat(next_job_fibers)
|
|
80
|
-
next_job_fibers.clear
|
|
81
189
|
end
|
|
82
190
|
|
|
83
|
-
def
|
|
191
|
+
def run_sources(run)
|
|
192
|
+
run.new_queues
|
|
193
|
+
|
|
194
|
+
if (unsnoozed = run.snoozed_sources_condition.waiting?)
|
|
195
|
+
run.snoozed_sources_condition.signal
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
allowed_tasks = run.allowed_sources_tasks
|
|
199
|
+
while (has_pending = @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) } ) || unsnoozed
|
|
200
|
+
unsnoozed = false
|
|
201
|
+
if has_pending
|
|
202
|
+
spawn_source_task(run, allowed_tasks)
|
|
203
|
+
end
|
|
204
|
+
run.wait_for_queues
|
|
205
|
+
end
|
|
206
|
+
ensure
|
|
207
|
+
run.close_queues
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
#### TODO DRY Had to duplicate to remove spawn_job_fiber
|
|
211
|
+
def run_next_pending_lazies(run)
|
|
212
|
+
smallest_depth = nil
|
|
213
|
+
@lazies_at_depth.each_key do |depth_key|
|
|
214
|
+
smallest_depth ||= depth_key
|
|
215
|
+
if depth_key < smallest_depth
|
|
216
|
+
smallest_depth = depth_key
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
if smallest_depth
|
|
221
|
+
lazies = @lazies_at_depth.delete(smallest_depth)
|
|
222
|
+
if !lazies.empty?
|
|
223
|
+
lazies.each_with_index do |l, idx|
|
|
224
|
+
append_job { l.value }
|
|
225
|
+
end
|
|
226
|
+
spawn_job_task(run) # Todo what was the last `true` condition?
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def spawn_source_task(run, num_tasks)
|
|
84
232
|
pending_sources = nil
|
|
85
233
|
@source_cache.each_value do |source_by_batch_params|
|
|
86
234
|
source_by_batch_params.each_value do |source|
|
|
@@ -92,18 +240,29 @@ module GraphQL
|
|
|
92
240
|
end
|
|
93
241
|
|
|
94
242
|
if pending_sources
|
|
243
|
+
if num_tasks == Float::INFINITY
|
|
244
|
+
num_tasks = pending_sources.size
|
|
245
|
+
end
|
|
95
246
|
fiber_vars = get_fiber_variables
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
trace&.
|
|
102
|
-
|
|
103
|
-
|
|
247
|
+
trace = run.trace
|
|
248
|
+
num_tasks.times do
|
|
249
|
+
run.root_task.async do |task|
|
|
250
|
+
Fiber[:__graphql_async_dataloader_run] = run
|
|
251
|
+
Fiber[:__graphql_async_dataloader_condition] = run.snoozed_sources_condition
|
|
252
|
+
trace&.dataloader_spawn_source_fiber(pending_sources)
|
|
253
|
+
set_fiber_variables(fiber_vars)
|
|
254
|
+
run.started_tasks.push(task)
|
|
255
|
+
while (source = pending_sources.shift)
|
|
256
|
+
trace&.begin_dataloader_source(source)
|
|
257
|
+
source.run_pending_keys
|
|
258
|
+
trace&.end_dataloader_source(source)
|
|
259
|
+
end
|
|
260
|
+
nil
|
|
261
|
+
ensure
|
|
262
|
+
run.finished_tasks.push($! || task)
|
|
263
|
+
cleanup_fiber
|
|
264
|
+
trace&.dataloader_fiber_exit
|
|
104
265
|
end
|
|
105
|
-
cleanup_fiber
|
|
106
|
-
trace&.dataloader_fiber_exit
|
|
107
266
|
end
|
|
108
267
|
end
|
|
109
268
|
end
|
|
@@ -51,9 +51,9 @@ module GraphQL
|
|
|
51
51
|
def value
|
|
52
52
|
query = @selections_step.query
|
|
53
53
|
set_current_field
|
|
54
|
-
query.current_trace.begin_execute_field(@field_definition, @
|
|
54
|
+
query.current_trace.begin_execute_field(@field_definition, @field_results, @arguments, query)
|
|
55
55
|
sync(@field_results)
|
|
56
|
-
query.current_trace.end_execute_field(@field_definition, @
|
|
56
|
+
query.current_trace.end_execute_field(@field_definition, @field_results, @arguments, query, @field_results)
|
|
57
57
|
@runner.add_step(self)
|
|
58
58
|
true
|
|
59
59
|
ensure
|
|
@@ -244,7 +244,7 @@ module GraphQL
|
|
|
244
244
|
@was_scoped = true
|
|
245
245
|
end
|
|
246
246
|
|
|
247
|
-
query.current_trace.begin_execute_field(@field_definition, @arguments,
|
|
247
|
+
query.current_trace.begin_execute_field(@field_definition, authorized_objects, @arguments, query)
|
|
248
248
|
|
|
249
249
|
if @runner.uses_runtime_directives
|
|
250
250
|
if @ast_nodes.nil? || @ast_nodes.size == 1
|
|
@@ -319,7 +319,7 @@ module GraphQL
|
|
|
319
319
|
@field_results = resolve_batch(authorized_objects, ctx, @arguments)
|
|
320
320
|
end
|
|
321
321
|
|
|
322
|
-
query.current_trace.end_execute_field(@field_definition, @arguments,
|
|
322
|
+
query.current_trace.end_execute_field(@field_definition, authorized_objects, @arguments, query, @field_results)
|
|
323
323
|
|
|
324
324
|
if any_lazy_results?
|
|
325
325
|
@runner.dataloader.lazy_at_depth(path.size, self)
|
data/lib/graphql/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: graphql
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.6.
|
|
4
|
+
version: 2.6.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robert Mosolgo
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-06-22 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: base64
|