master_loader 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/master_loader/version.rb +1 -1
- data/lib/master_loader.rb +28 -36
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd83b96c1af9e69faf722df9b11e111d28fcf27e32c6563d01a010eaee9c0b54
|
4
|
+
data.tar.gz: 4637e7af9cab59032ae49f095447c84a8c5802dcd7af316902cc7f1aed552c0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1017e771dff8a4f26b97b066e50aa2a0618b5930a142daf7a7890b84e345d6fc28cd1bfbac700bb750bf94aa03acffdf8f028a6f21bc81457ad2a804e2f74b25
|
7
|
+
data.tar.gz: 0f248838aeaf259a7fd599cd91c858dcb7df3725c1ce2c1c6a3f0b45a2ffe555fe33be55503252ed5cbd0c22fe5cef8016bb29e1a0c42d5a8aeb18264d253a31
|
data/lib/master_loader.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'concurrent'
|
2
|
-
|
3
1
|
class DelayedResult
|
4
2
|
def initialize(&resolver)
|
5
3
|
@resolver = resolver
|
@@ -19,7 +17,7 @@ class DelayedResult
|
|
19
17
|
end
|
20
18
|
|
21
19
|
def value!
|
22
|
-
@value ||= @resolver.call
|
20
|
+
@value ||= @resolver.call.yield_self do |val|
|
23
21
|
if val&.is_a?(DelayedResult)
|
24
22
|
val.value!
|
25
23
|
else
|
@@ -34,6 +32,16 @@ class DelayedResult
|
|
34
32
|
end
|
35
33
|
|
36
34
|
class MasterLoader
|
35
|
+
class Cache < ::Hash
|
36
|
+
def compute_if_absent(key, &block)
|
37
|
+
if self.has_key?(key)
|
38
|
+
self.fetch(key)
|
39
|
+
else
|
40
|
+
self[key] = block.call(key)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
37
45
|
class NoCache
|
38
46
|
def compute_if_absent(_key)
|
39
47
|
yield
|
@@ -41,13 +49,11 @@ class MasterLoader
|
|
41
49
|
end
|
42
50
|
|
43
51
|
class Batch
|
44
|
-
attr_accessor :name
|
45
|
-
attr_accessor :fulfilled
|
52
|
+
attr_accessor :name, :fulfilled
|
46
53
|
|
47
54
|
def initialize(loader_block, name: nil, max_batch_size: Float::INFINITY)
|
48
55
|
@name = name
|
49
|
-
@queue =
|
50
|
-
@lock = Concurrent::ReadWriteLock.new
|
56
|
+
@queue = []
|
51
57
|
@loader_block = loader_block
|
52
58
|
@max_batch_size = max_batch_size
|
53
59
|
@fulfilled = false
|
@@ -59,23 +65,15 @@ class MasterLoader
|
|
59
65
|
|
60
66
|
DelayedResult.new do
|
61
67
|
results = if @fulfilled
|
62
|
-
@
|
63
|
-
@results
|
64
|
-
end
|
68
|
+
@results
|
65
69
|
else
|
66
|
-
@
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
normalize_results(r.value!)
|
74
|
-
else
|
75
|
-
normalize_results(r)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
70
|
+
@fulfilled = true
|
71
|
+
r = @loader_block.call(@queue)
|
72
|
+
@results = if r.is_a?(DelayedResult)
|
73
|
+
normalize_results(r.value!)
|
74
|
+
else
|
75
|
+
normalize_results(r)
|
76
|
+
end
|
79
77
|
end
|
80
78
|
|
81
79
|
unless results.key?(key)
|
@@ -124,12 +122,12 @@ class MasterLoader
|
|
124
122
|
@cache = if options.has_key?(:cache)
|
125
123
|
options.delete(:cache) || NoCache.new
|
126
124
|
else
|
127
|
-
|
125
|
+
Cache.new
|
128
126
|
end
|
129
127
|
@max_batch_size = options.fetch(:max_batch_size, Float::INFINITY)
|
130
128
|
|
131
|
-
@interceptor = options.delete(:interceptor) ||
|
132
|
-
|
129
|
+
@interceptor = options.delete(:interceptor) || lambda { |n|
|
130
|
+
lambda { |ids|
|
133
131
|
n.call(ids)
|
134
132
|
}
|
135
133
|
}
|
@@ -138,9 +136,7 @@ class MasterLoader
|
|
138
136
|
end
|
139
137
|
|
140
138
|
def load(key)
|
141
|
-
if key.nil?
|
142
|
-
raise TypeError, "#load must be called with a key, but got: nil"
|
143
|
-
end
|
139
|
+
raise TypeError, "#load must be called with a key, but got: nil" if key.nil?
|
144
140
|
|
145
141
|
result = retrieve_from_cache(key) do
|
146
142
|
batch.queue(key)
|
@@ -154,9 +150,7 @@ class MasterLoader
|
|
154
150
|
end
|
155
151
|
|
156
152
|
def load_many(keys)
|
157
|
-
unless keys.is_a?(Array)
|
158
|
-
raise TypeError, "#load_many must be called with an Array, but got: #{keys.class.name}"
|
159
|
-
end
|
153
|
+
raise TypeError, "#load_many must be called with an Array, but got: #{keys.class.name}" unless keys.is_a?(Array)
|
160
154
|
|
161
155
|
delayed_results = keys.map(&method(:load))
|
162
156
|
DelayedResult.new do
|
@@ -172,9 +166,7 @@ class MasterLoader
|
|
172
166
|
end
|
173
167
|
end
|
174
168
|
|
175
|
-
def retrieve_from_cache(key)
|
176
|
-
@cache.compute_if_absent(key)
|
177
|
-
yield
|
178
|
-
end
|
169
|
+
def retrieve_from_cache(key, &block)
|
170
|
+
@cache.compute_if_absent(key, &block)
|
179
171
|
end
|
180
172
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: master_loader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Caleb Land
|
@@ -9,21 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2021-09-20 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: concurrent-ruby
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.1'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.1'
|
12
|
+
dependencies: []
|
27
13
|
description: A data loading utility to batch loading of promises. It can be used with
|
28
14
|
graphql gem.
|
29
15
|
email:
|