async-pool 0.3.3 → 0.3.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 +4 -4
- data/lib/async/pool/controller.rb +67 -6
- data/lib/async/pool/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53496ca8f02b057c94d8cef37e92f7d14bb3d7062267ea53f363d5ca3c2ee7d4
|
4
|
+
data.tar.gz: b59bb3a498bb16b1306eea4b6bcb765efa60a479701f546a3c2b6785ff5203e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f53063512c044675725eed75b72346644a36c99704bf2f1559692420f7176b88063cb79200d4a24f19f8cd081be224e307a811d91dc8a94923cccb87cf850cc4
|
7
|
+
data.tar.gz: 366355082c92722989dd76607f611fd81f520844b8733e15872db4164a146bc2e257e40f316bc87c173a49b65d465e07cccdf459fea242b9c8445841c13f7580
|
@@ -32,9 +32,13 @@ module Async
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def initialize(constructor, limit: nil)
|
35
|
+
# All available resources:
|
35
36
|
@resources = {}
|
36
37
|
|
38
|
+
# Resources which may be available to be acquired:
|
39
|
+
# This list may contain false positives, or resources which were okay but have since entered a state which is unusuable.
|
37
40
|
@available = []
|
41
|
+
|
38
42
|
@notification = Async::Notification.new
|
39
43
|
|
40
44
|
@limit = limit
|
@@ -45,7 +49,7 @@ module Async
|
|
45
49
|
@gardener = nil
|
46
50
|
end
|
47
51
|
|
48
|
-
# @
|
52
|
+
# @attribute [Hash(Resource, Integer)] all allocated resources, and their associated usage.
|
49
53
|
attr :resources
|
50
54
|
|
51
55
|
def size
|
@@ -66,6 +70,11 @@ module Async
|
|
66
70
|
return false
|
67
71
|
end
|
68
72
|
|
73
|
+
# Whether there are available resources, i.e. whether {#acquire} can reuse an existing resource.
|
74
|
+
def available?
|
75
|
+
@available.any?
|
76
|
+
end
|
77
|
+
|
69
78
|
# Wait until a pool resource has been freed.
|
70
79
|
def wait
|
71
80
|
@notification.wait
|
@@ -119,7 +128,9 @@ module Async
|
|
119
128
|
unused = []
|
120
129
|
|
121
130
|
@resources.each do |resource, usage|
|
122
|
-
|
131
|
+
if usage.zero?
|
132
|
+
unused << resource
|
133
|
+
end
|
123
134
|
end
|
124
135
|
|
125
136
|
unused.each do |resource|
|
@@ -132,6 +143,14 @@ module Async
|
|
132
143
|
break if @resources.size <= retain
|
133
144
|
end
|
134
145
|
|
146
|
+
# Update availability list:
|
147
|
+
@available.clear
|
148
|
+
@resources.each do |resource, usage|
|
149
|
+
if usage < resource.concurrency and resource.reusable?
|
150
|
+
@available << resource
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
135
154
|
return unused.size
|
136
155
|
end
|
137
156
|
|
@@ -170,11 +189,42 @@ module Async
|
|
170
189
|
end.join(";")
|
171
190
|
end
|
172
191
|
|
192
|
+
def usage
|
193
|
+
@resources.count{|resource, usage| usage > 0}
|
194
|
+
end
|
195
|
+
|
196
|
+
def free
|
197
|
+
@resources.count{|resource, usage| usage == 0}
|
198
|
+
end
|
199
|
+
|
200
|
+
# @returns [Boolean] Whether the number of available resources is excessive and we should retire some.
|
201
|
+
def overflowing?
|
202
|
+
if @resources.any?
|
203
|
+
(self.free.to_f / @resources.size) > 0.5
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
173
207
|
def reuse(resource)
|
174
208
|
Async.logger.debug(self) {"Reuse #{resource}"}
|
209
|
+
usage = @resources[resource]
|
210
|
+
|
211
|
+
if usage.zero?
|
212
|
+
raise "Trying to reuse unacquired resource: #{resource}!"
|
213
|
+
end
|
214
|
+
|
215
|
+
# We retire resources when adding to the @available list would overflow our pool:
|
216
|
+
if usage == 1
|
217
|
+
if overflowing?
|
218
|
+
return retire(resource)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# If the resource was fully utilized, it now becomes available:
|
223
|
+
if usage == resource.concurrency
|
224
|
+
@available.push(resource)
|
225
|
+
end
|
175
226
|
|
176
|
-
@resources[resource]
|
177
|
-
@available.push(resource)
|
227
|
+
@resources[resource] = usage - 1
|
178
228
|
|
179
229
|
@notification.signal
|
180
230
|
end
|
@@ -194,6 +244,7 @@ module Async
|
|
194
244
|
return resource
|
195
245
|
end
|
196
246
|
|
247
|
+
# @returns [Object] A new resource in a "used" state.
|
197
248
|
def create_resource
|
198
249
|
self.start_gardener
|
199
250
|
|
@@ -201,18 +252,27 @@ module Async
|
|
201
252
|
if resource = @constructor.call
|
202
253
|
@resources[resource] = 1
|
203
254
|
|
204
|
-
|
255
|
+
# Make the resource available if it can be used multiple times:
|
256
|
+
if resource.concurrency > 1
|
257
|
+
@available.push(resource)
|
258
|
+
end
|
205
259
|
end
|
206
260
|
|
207
261
|
return resource
|
208
262
|
end
|
209
263
|
|
264
|
+
# @returns [Object] An existing resource in a "used" state.
|
210
265
|
def available_resource
|
211
266
|
@guard.acquire do
|
212
267
|
while resource = @available.last
|
213
268
|
if usage = @resources[resource] and usage < resource.concurrency
|
214
269
|
if resource.viable?
|
215
|
-
@resources[resource] += 1
|
270
|
+
usage = (@resources[resource] += 1)
|
271
|
+
|
272
|
+
if usage == resource.concurrency
|
273
|
+
# The resource is used up to it's limit:
|
274
|
+
@available.pop
|
275
|
+
end
|
216
276
|
|
217
277
|
return resource
|
218
278
|
else
|
@@ -220,6 +280,7 @@ module Async
|
|
220
280
|
@available.pop
|
221
281
|
end
|
222
282
|
else
|
283
|
+
# The resource has been removed already, so skip it and remove it from the availability list.
|
223
284
|
@available.pop
|
224
285
|
end
|
225
286
|
end
|
data/lib/async/pool/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|