graphiti 1.12.0 → 1.12.1
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/graphiti/scope.rb +47 -1
- data/lib/graphiti/sideload/polymorphic_belongs_to.rb +14 -1
- data/lib/graphiti/sideload.rb +29 -0
- data/lib/graphiti/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96af714433c7faece37e74ab67dad245d5e03396ec391be80cec77622d231faf
|
|
4
|
+
data.tar.gz: 34ce7b027042cd3cda4cf656ba8d96a05908dc0edbe9104ee4fb3597c5970971
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d0c414812bbccef7567e2e8e48e6b6353582d7801aa71a893f368eb12c71906e1420a1f40dd6d18c8ad6e5d43e3585983340d409742303112dd2737810a26d1
|
|
7
|
+
data.tar.gz: 59774b04ced36164343ddb12a7f2aa2026d2981b0c9df1b6bb92f127abb856467403e64cf72ec15bfde012511f1fa5908bf38bbbecea1becc2527d61df346d72
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
graphiti changelog
|
|
2
2
|
|
|
3
|
+
## [1.12.1](https://github.com/graphiti-api/graphiti/compare/v1.12.0...v1.12.1) (2026-07-29)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Performance Improvements
|
|
7
|
+
|
|
8
|
+
* skip promise machinery when concurrency is disabled ([#510](https://github.com/graphiti-api/graphiti/issues/510)) ([b2e5f37](https://github.com/graphiti-api/graphiti/commit/b2e5f37428f7628b9fadd03823bd68552e125af0)), closes [#472](https://github.com/graphiti-api/graphiti/issues/472) [#497](https://github.com/graphiti-api/graphiti/issues/497) [#505](https://github.com/graphiti-api/graphiti/issues/505)
|
|
9
|
+
|
|
3
10
|
# [1.12.0](https://github.com/graphiti-api/graphiti/compare/v1.11.1...v1.12.0) (2026-07-29)
|
|
4
11
|
|
|
5
12
|
|
data/lib/graphiti/scope.rb
CHANGED
|
@@ -42,11 +42,20 @@ module Graphiti
|
|
|
42
42
|
}
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
def resolve
|
|
45
|
+
def resolve(&blk)
|
|
46
|
+
# When concurrency is disabled, take a synchronous path that mirrors the
|
|
47
|
+
# pre-1.8 semantics. This avoids allocating Concurrent::Promises futures,
|
|
48
|
+
# Thread/Fiber storage snapshots, and Rails executor wrappers on every
|
|
49
|
+
# request purely to drive a thread pool that is intentionally synchronous.
|
|
50
|
+
# See https://github.com/graphiti-api/graphiti/issues/505
|
|
51
|
+
return sync_resolve(&blk) unless Graphiti.config.concurrency
|
|
52
|
+
|
|
46
53
|
future_resolve.value!
|
|
47
54
|
end
|
|
48
55
|
|
|
49
56
|
def resolve_sideloads(results)
|
|
57
|
+
return sync_resolve_sideloads(results) unless Graphiti.config.concurrency
|
|
58
|
+
|
|
50
59
|
future_resolve_sideloads(results).value!
|
|
51
60
|
end
|
|
52
61
|
|
|
@@ -113,6 +122,43 @@ module Graphiti
|
|
|
113
122
|
|
|
114
123
|
private
|
|
115
124
|
|
|
125
|
+
# Synchronous counterpart to #future_resolve, used when concurrency is off.
|
|
126
|
+
# Resolves the resource and its sideloads inline without any promise
|
|
127
|
+
# machinery. See #resolve.
|
|
128
|
+
def sync_resolve
|
|
129
|
+
return [] if @query.zero_results?
|
|
130
|
+
|
|
131
|
+
resolved = broadcast_data { |payload|
|
|
132
|
+
@object = @resource.before_resolve(@object, @query)
|
|
133
|
+
payload[:results] = @resource.resolve(@object)
|
|
134
|
+
payload[:results]
|
|
135
|
+
}
|
|
136
|
+
resolved.compact!
|
|
137
|
+
assign_serializer(resolved)
|
|
138
|
+
yield resolved if block_given?
|
|
139
|
+
@opts[:after_resolve]&.call(resolved)
|
|
140
|
+
sync_resolve_sideloads(resolved) unless @query.sideloads.empty?
|
|
141
|
+
resolved
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Synchronous counterpart to #future_resolve_sideloads, used when
|
|
145
|
+
# concurrency is off. Resolves each sideload inline. See #resolve_sideloads.
|
|
146
|
+
def sync_resolve_sideloads(results)
|
|
147
|
+
return if results == []
|
|
148
|
+
|
|
149
|
+
@query.sideloads.each_pair do |name, q|
|
|
150
|
+
sideload = @resource.class.sideload(name)
|
|
151
|
+
next if sideload.nil? || sideload.shared_remote?
|
|
152
|
+
|
|
153
|
+
Graphiti.config.before_sideload&.call(Graphiti.context)
|
|
154
|
+
sideload.resolve(results, q, @resource)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Match pre-1.8 semantics: the non-concurrent resolve_sideloads returned
|
|
158
|
+
# nil (not the sideloads Hash). Callers don't rely on the return value.
|
|
159
|
+
nil
|
|
160
|
+
end
|
|
161
|
+
|
|
116
162
|
def future_resolve_sideloads(results)
|
|
117
163
|
return Concurrent::Promises.fulfilled_future(nil, self.class.global_thread_pool_executor) if results == []
|
|
118
164
|
|
|
@@ -108,7 +108,20 @@ class Graphiti::Sideload::PolymorphicBelongsTo < Graphiti::Sideload::BelongsTo
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def resolve(parents, query, graph_parent)
|
|
111
|
-
future_resolve(parents, query, graph_parent).value!
|
|
111
|
+
return future_resolve(parents, query, graph_parent).value! if Graphiti.config.concurrency
|
|
112
|
+
|
|
113
|
+
parents.group_by(&grouper.field_name).each_pair do |group_name, group|
|
|
114
|
+
next if group_name.nil? || grouper.ignore?(group_name)
|
|
115
|
+
|
|
116
|
+
match = ->(c) { c.group_name == group_name.to_sym }
|
|
117
|
+
if (sideload = children.values.find(&match))
|
|
118
|
+
duped = remove_invalid_sideloads(sideload.resource, query)
|
|
119
|
+
sideload.resolve(group, duped, graph_parent)
|
|
120
|
+
else
|
|
121
|
+
err = ::Graphiti::Errors::PolymorphicSideloadChildNotFound
|
|
122
|
+
raise err.new(self, group_name)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
112
125
|
end
|
|
113
126
|
|
|
114
127
|
def future_resolve(parents, query, graph_parent)
|
data/lib/graphiti/sideload.rb
CHANGED
|
@@ -240,6 +240,8 @@ module Graphiti
|
|
|
240
240
|
end
|
|
241
241
|
|
|
242
242
|
def load(parents, query, graph_parent)
|
|
243
|
+
return build_resource_proxy(parents, query, graph_parent).to_a unless Graphiti.config.concurrency
|
|
244
|
+
|
|
243
245
|
future_load(parents, query, graph_parent).value!
|
|
244
246
|
end
|
|
245
247
|
|
|
@@ -290,6 +292,33 @@ module Graphiti
|
|
|
290
292
|
children.replace(associated) if track_associated
|
|
291
293
|
end
|
|
292
294
|
|
|
295
|
+
# Synchronous counterpart to #future_resolve, used when concurrency is off.
|
|
296
|
+
# Mirrors #future_resolve but resolves inline via the synchronous
|
|
297
|
+
# Scope#resolve / #load paths (no promises). See Scope#sync_resolve_sideloads.
|
|
298
|
+
def resolve(parents, query, graph_parent)
|
|
299
|
+
return future_resolve(parents, query, graph_parent).value! if Graphiti.config.concurrency
|
|
300
|
+
|
|
301
|
+
if single? && parents.length > 1
|
|
302
|
+
raise Errors::SingularSideload.new(self, parents.length)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
if self.class.scope_proc
|
|
306
|
+
sideload_scope = fire_scope(parents)
|
|
307
|
+
sideload_scope = Scope.new sideload_scope,
|
|
308
|
+
resource,
|
|
309
|
+
query,
|
|
310
|
+
parent: graph_parent,
|
|
311
|
+
sideload: self,
|
|
312
|
+
sideload_parent_length: parents.length,
|
|
313
|
+
default_paginate: false
|
|
314
|
+
sideload_scope.resolve do |sideload_results|
|
|
315
|
+
fire_assign(parents, sideload_results)
|
|
316
|
+
end
|
|
317
|
+
else
|
|
318
|
+
load(parents, query, graph_parent)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
293
322
|
def future_resolve(parents, query, graph_parent)
|
|
294
323
|
if single? && parents.length > 1
|
|
295
324
|
raise Errors::SingularSideload.new(self, parents.length)
|
data/lib/graphiti/version.rb
CHANGED