async-pool 0.7.1 → 0.8.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
- checksums.yaml.gz.sig +0 -0
- data/lib/async/pool/controller.rb +86 -19
- data/lib/async/pool/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +30 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d877fb908af8482011de394630982c4c593e36a5efd9ef19a885bba5774f6e8
|
4
|
+
data.tar.gz: be2d7efd8c65a9eec5237acc4f432e76a3f401da0b13e7e10b089f9849382f2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e472af40018c10b2a8d726fc31b04ea96557d790c55e4fe6449a891b048c96da66794926eb7ca726195f778d0bea1e6c9d762b274a06a0922f382d5a8794ab7
|
7
|
+
data.tar.gz: 8abacfdcb4b32eb573e0108aecdbdd7ff385386e8a8de2710550b976a81467286e73fa8f36292162e801d5f000fc2a222aabf99f7cf334a35d7e22e47833ded1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -11,6 +11,9 @@ require 'async'
|
|
11
11
|
require 'async/notification'
|
12
12
|
require 'async/semaphore'
|
13
13
|
|
14
|
+
require 'traces'
|
15
|
+
require 'metrics'
|
16
|
+
|
14
17
|
module Async
|
15
18
|
module Pool
|
16
19
|
# A resource pool controller.
|
@@ -154,20 +157,20 @@ module Async
|
|
154
157
|
retire(resource) unless processed
|
155
158
|
end
|
156
159
|
|
157
|
-
|
158
|
-
|
159
|
-
@available.clear
|
160
|
+
def drain
|
161
|
+
Console.debug(self, "Draining pool...", size: @resources.size)
|
160
162
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
if usage > 0
|
165
|
-
Console.warn(self, resource: resource, usage: usage) {"Closing resource while still in use!"}
|
166
|
-
end
|
167
|
-
|
168
|
-
resource.close
|
163
|
+
# Enumerate all existing resources and retire them:
|
164
|
+
while resource = acquire_existing_resource
|
165
|
+
retire(resource)
|
169
166
|
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Close all resources in the pool.
|
170
|
+
def close
|
171
|
+
self.drain
|
170
172
|
|
173
|
+
@available.clear
|
171
174
|
@gardener&.stop
|
172
175
|
end
|
173
176
|
|
@@ -224,6 +227,8 @@ module Async
|
|
224
227
|
def start_gardener
|
225
228
|
return if @gardener
|
226
229
|
|
230
|
+
@gardener = true
|
231
|
+
|
227
232
|
Async(transient: true, annotation: "#{self.class} Gardener") do |task|
|
228
233
|
@gardener = task
|
229
234
|
|
@@ -262,6 +267,7 @@ module Async
|
|
262
267
|
|
263
268
|
def reuse(resource)
|
264
269
|
Console.debug(self) {"Reuse #{resource}"}
|
270
|
+
|
265
271
|
usage = @resources[resource]
|
266
272
|
|
267
273
|
if usage.nil? || usage.zero?
|
@@ -286,11 +292,7 @@ module Async
|
|
286
292
|
@notification.wait
|
287
293
|
end
|
288
294
|
|
289
|
-
|
290
|
-
|
291
|
-
# if resource.concurrency > 1
|
292
|
-
# @notification.signal
|
293
|
-
# end
|
295
|
+
# Be careful not to context switch or fail here.
|
294
296
|
|
295
297
|
return resource
|
296
298
|
end
|
@@ -318,19 +320,40 @@ module Async
|
|
318
320
|
def available_resource
|
319
321
|
resource = nil
|
320
322
|
|
323
|
+
Console.debug(self, "Acquiring concurrency guard...", blocking: @guard.blocking?)
|
324
|
+
|
321
325
|
@guard.acquire do
|
322
|
-
|
326
|
+
Console.debug(self, "Acquired concurrency guard.")
|
327
|
+
|
328
|
+
resource = acquire_or_create_resource
|
323
329
|
end
|
324
330
|
|
325
331
|
return resource
|
326
|
-
rescue Exception
|
332
|
+
rescue Exception => error
|
327
333
|
reuse(resource) if resource
|
328
334
|
raise
|
329
335
|
end
|
330
336
|
|
331
337
|
private
|
332
338
|
|
333
|
-
|
339
|
+
# Acquire an existing resource with zero usage.
|
340
|
+
# If there are resources that are in use, wait until they are released.
|
341
|
+
def acquire_existing_resource
|
342
|
+
while @resources.any?
|
343
|
+
@resources.each do |resource, usage|
|
344
|
+
if usage == 0
|
345
|
+
return resource
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
@notification.wait
|
350
|
+
end
|
351
|
+
|
352
|
+
# Only when the pool has been completely drained, return nil:
|
353
|
+
return nil
|
354
|
+
end
|
355
|
+
|
356
|
+
def acquire_or_create_resource
|
334
357
|
while resource = @available.last
|
335
358
|
if usage = @resources[resource] and usage < resource.concurrency
|
336
359
|
if resource.viable?
|
@@ -358,6 +381,50 @@ module Async
|
|
358
381
|
return create_resource
|
359
382
|
end
|
360
383
|
end
|
384
|
+
|
385
|
+
Traces::Provider(self) do
|
386
|
+
def create_resource(...)
|
387
|
+
attributes = {
|
388
|
+
concurrency: @guard.limit,
|
389
|
+
size: @resources.size,
|
390
|
+
limit: @limit,
|
391
|
+
}
|
392
|
+
|
393
|
+
Traces.trace('async.pool.create', attributes: attributes) {super}
|
394
|
+
end
|
395
|
+
|
396
|
+
def drain(...)
|
397
|
+
attributes = {
|
398
|
+
size: @resources.size,
|
399
|
+
}
|
400
|
+
|
401
|
+
Traces.trace('async.pool.drain', attributes: attributes) {super}
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
Metrics::Provider(self) do
|
406
|
+
ACQUIRE_COUNT = Metrics.metric('async.pool.acquire', :counter, description: 'Number of times a resource was invoked.')
|
407
|
+
RELEASE_COUNT = Metrics.metric('async.pool.release', :counter, description: 'Number of times a resource was released.')
|
408
|
+
RETIRE_COUNT = Metrics.metric('async.pool.retire', :counter, description: 'Number of times a resource was retired.')
|
409
|
+
|
410
|
+
def acquire(...)
|
411
|
+
ACQUIRE_COUNT.emit(1)
|
412
|
+
|
413
|
+
super
|
414
|
+
end
|
415
|
+
|
416
|
+
def release(...)
|
417
|
+
super.tap do
|
418
|
+
RELEASE_COUNT.emit(1)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def retire(...)
|
423
|
+
super.tap do
|
424
|
+
RETIRE_COUNT.emit(1)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
361
428
|
end
|
362
429
|
end
|
363
430
|
end
|
data/lib/async/pool/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -40,7 +40,7 @@ cert_chain:
|
|
40
40
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
41
41
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
42
42
|
-----END CERTIFICATE-----
|
43
|
-
date: 2024-08-
|
43
|
+
date: 2024-08-26 00:00:00.000000000 Z
|
44
44
|
dependencies:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: async
|
@@ -56,6 +56,34 @@ dependencies:
|
|
56
56
|
- - ">="
|
57
57
|
- !ruby/object:Gem::Version
|
58
58
|
version: '1.25'
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: metrics
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: traces
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
type: :runtime
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
59
87
|
description:
|
60
88
|
email:
|
61
89
|
executables: []
|
metadata.gz.sig
CHANGED
Binary file
|