async-pool 0.11.1 → 0.12.0
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 +48 -41
- data/lib/async/pool/version.rb +2 -2
- data/license.md +2 -1
- data/readme.md +24 -4
- data/releases.md +5 -1
- data.tar.gz.sig +4 -2
- metadata +6 -3
- 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: 8261d789df6f1e5666e9994a6b977a9a51f7c196701fffebe2f26eca28aab213
|
|
4
|
+
data.tar.gz: 9db4443e7e225ed235c8700c2a89292bced23af536abf5d5a625520ccc470c5f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e570ea6d402c540b87f604e84b5df47744a69d6eb99f423069b5cae560e6f8e8cd75102dc7e6c9c8514671099a00cd7596a6c2f4a0ab551857684b3cf27f2c02
|
|
7
|
+
data.tar.gz: 34c158ab5216a2c6a8c9fc930f6f0042fc19b05a71fe3659e4ebd06dc91094effb18c8c36c1c01c160d32d2cc306a6957496c6bf9d3f78553e8cfe5dbf939a0d
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2019-
|
|
4
|
+
# Copyright, 2019-2026, by Samuel Williams.
|
|
5
5
|
# Copyright, 2020, by Simon Perepelitsa.
|
|
6
6
|
# Copyright, 2024, by Thomas Morgan.
|
|
7
7
|
# Copyright, 2025, by Jean Boussier.
|
|
8
|
+
# Copyright, 2026, by William T. Nelson.
|
|
8
9
|
|
|
9
10
|
require "console/logger"
|
|
10
11
|
|
|
11
12
|
require "async"
|
|
12
13
|
require "async/semaphore"
|
|
13
14
|
|
|
15
|
+
require "set"
|
|
14
16
|
require "thread"
|
|
15
17
|
|
|
16
18
|
module Async
|
|
@@ -26,9 +28,9 @@ module Async
|
|
|
26
28
|
#
|
|
27
29
|
# @parameter constructor [Proc] A block which creates a new resource.
|
|
28
30
|
# @parameter limit [Integer | Nil] The maximum number of resources that this pool can have at any given time. If nil, the pool can have an unlimited number of resources.
|
|
29
|
-
# @parameter concurrency [Integer] The maximum number of concurrent tasks that can be creating a new resource.
|
|
31
|
+
# @parameter concurrency [Integer] The maximum number of concurrent tasks that can be creating a new resource. Defaults to 1 to ensure the pool limit is enforced. Higher values may result in more resources being created than the limit under high load.
|
|
30
32
|
# @parameter policy [Policy] The pool policy.
|
|
31
|
-
def initialize(constructor, limit: nil, concurrency:
|
|
33
|
+
def initialize(constructor, limit: nil, concurrency: 1, policy: nil, tags: nil)
|
|
32
34
|
@constructor = constructor
|
|
33
35
|
@limit = limit
|
|
34
36
|
|
|
@@ -40,12 +42,12 @@ module Async
|
|
|
40
42
|
|
|
41
43
|
@tags = tags
|
|
42
44
|
|
|
43
|
-
# All
|
|
44
|
-
@resources = {}
|
|
45
|
+
# All allocated resources. Each resource is tracked by identity, irrespective of any value equality it may define:
|
|
46
|
+
@resources = {}.compare_by_identity
|
|
45
47
|
|
|
46
|
-
# Resources which may be available to be acquired
|
|
47
|
-
# This
|
|
48
|
-
@available =
|
|
48
|
+
# Resources which may be available to be acquired. Resources are compared by identity and acquired in insertion order. Adding an existing resource preserves its position; a fully utilized resource is removed and reinserted at the end when capacity becomes available again.
|
|
49
|
+
# This set may contain false positives, or resources which were okay but have since entered a state which is unusable.
|
|
50
|
+
@available = Set.new.compare_by_identity
|
|
49
51
|
|
|
50
52
|
# Used to signal when a resource has been released:
|
|
51
53
|
@mutex = Thread::Mutex.new
|
|
@@ -165,16 +167,31 @@ module Async
|
|
|
165
167
|
|
|
166
168
|
# Make the resource resources and let waiting tasks know that there is something resources.
|
|
167
169
|
def release(resource)
|
|
168
|
-
|
|
170
|
+
unless usage = decrement_usage(resource)
|
|
171
|
+
return false
|
|
172
|
+
end
|
|
169
173
|
|
|
170
|
-
# A resource that is not good should also not be reusable.
|
|
171
174
|
if resource.reusable?
|
|
172
|
-
|
|
175
|
+
@available.add(resource)
|
|
176
|
+
else
|
|
177
|
+
# The resource must not be acquired again, but it cannot be retired until all existing users have released it:
|
|
178
|
+
@available.delete(resource)
|
|
179
|
+
|
|
180
|
+
if usage.zero?
|
|
181
|
+
retire(resource)
|
|
182
|
+
resource = nil
|
|
183
|
+
return true
|
|
184
|
+
end
|
|
173
185
|
end
|
|
174
186
|
|
|
187
|
+
@mutex.synchronize{@condition.broadcast}
|
|
188
|
+
|
|
175
189
|
# @policy.released(self, resource)
|
|
190
|
+
|
|
191
|
+
resource = nil
|
|
192
|
+
return true
|
|
176
193
|
ensure
|
|
177
|
-
retire(resource)
|
|
194
|
+
retire(resource) if resource
|
|
178
195
|
end
|
|
179
196
|
|
|
180
197
|
# Drain the pool, closing all resources.
|
|
@@ -234,7 +251,7 @@ module Async
|
|
|
234
251
|
def retire(resource)
|
|
235
252
|
Console.debug(self){"Retire #{resource}"}
|
|
236
253
|
|
|
237
|
-
@resources.delete(resource)
|
|
254
|
+
return false unless @resources.delete(resource)
|
|
238
255
|
|
|
239
256
|
resource.close
|
|
240
257
|
|
|
@@ -281,27 +298,6 @@ module Async
|
|
|
281
298
|
# @resources.count{|resource, usage| usage == 0}
|
|
282
299
|
# end
|
|
283
300
|
|
|
284
|
-
def reuse(resource)
|
|
285
|
-
Console.debug(self){"Reuse #{resource}"}
|
|
286
|
-
|
|
287
|
-
usage = @resources[resource]
|
|
288
|
-
|
|
289
|
-
if usage.nil? || usage.zero?
|
|
290
|
-
raise "Trying to reuse unacquired resource: #{resource}!"
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
# If the resource was fully utilized, it now becomes available:
|
|
294
|
-
if usage == resource.concurrency
|
|
295
|
-
@available.push(resource)
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
@resources[resource] = usage - 1
|
|
299
|
-
|
|
300
|
-
@mutex.synchronize{@condition.broadcast}
|
|
301
|
-
|
|
302
|
-
return true
|
|
303
|
-
end
|
|
304
|
-
|
|
305
301
|
def wait_for_resource
|
|
306
302
|
# If we fail to create a resource (below), we will end up waiting for one to become resources.
|
|
307
303
|
until resource = available_resource
|
|
@@ -321,7 +317,7 @@ module Async
|
|
|
321
317
|
|
|
322
318
|
# Make the resource available if it can be used multiple times:
|
|
323
319
|
if resource.concurrency > 1
|
|
324
|
-
@available.
|
|
320
|
+
@available.add(resource)
|
|
325
321
|
end
|
|
326
322
|
end
|
|
327
323
|
|
|
@@ -340,12 +336,23 @@ module Async
|
|
|
340
336
|
|
|
341
337
|
return resource
|
|
342
338
|
rescue Exception
|
|
343
|
-
|
|
339
|
+
release(resource) if resource
|
|
344
340
|
raise
|
|
345
341
|
end
|
|
346
342
|
|
|
347
343
|
private
|
|
348
344
|
|
|
345
|
+
def decrement_usage(resource)
|
|
346
|
+
usage = @resources[resource]
|
|
347
|
+
return unless usage
|
|
348
|
+
|
|
349
|
+
if usage.zero?
|
|
350
|
+
raise "Trying to reuse unacquired resource: #{resource}!"
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
return @resources[resource] = usage - 1
|
|
354
|
+
end
|
|
355
|
+
|
|
349
356
|
# Acquire an existing resource with zero usage.
|
|
350
357
|
# If there are resources that are in use, wait until they are released.
|
|
351
358
|
def acquire_existing_resource
|
|
@@ -362,24 +369,24 @@ module Async
|
|
|
362
369
|
end
|
|
363
370
|
|
|
364
371
|
def acquire_or_create_resource
|
|
365
|
-
while resource = @available.
|
|
372
|
+
while resource = @available.first
|
|
366
373
|
if usage = @resources[resource] and usage < resource.concurrency
|
|
367
374
|
if resource.viable?
|
|
368
375
|
usage = (@resources[resource] += 1)
|
|
369
376
|
|
|
370
377
|
if usage == resource.concurrency
|
|
371
378
|
# The resource is used up to it's limit:
|
|
372
|
-
@available.
|
|
379
|
+
@available.delete(resource)
|
|
373
380
|
end
|
|
374
381
|
|
|
375
382
|
return resource
|
|
376
383
|
else
|
|
377
|
-
|
|
378
|
-
|
|
384
|
+
@available.delete(resource)
|
|
385
|
+
retire(resource) if usage.zero?
|
|
379
386
|
end
|
|
380
387
|
else
|
|
381
388
|
# The resource has been removed already, so skip it and remove it from the availability list.
|
|
382
|
-
@available.
|
|
389
|
+
@available.delete(resource)
|
|
383
390
|
end
|
|
384
391
|
end
|
|
385
392
|
|
data/lib/async/pool/version.rb
CHANGED
data/license.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# MIT License
|
|
2
2
|
|
|
3
|
-
Copyright, 2019-
|
|
3
|
+
Copyright, 2019-2026, by Samuel Williams.
|
|
4
4
|
Copyright, 2020, by Simon Perepelitsa.
|
|
5
5
|
Copyright, 2021, by Olle Jonsson.
|
|
6
6
|
Copyright, 2024, by Thomas Morgan.
|
|
7
7
|
Copyright, 2025, by Jean Boussier.
|
|
8
|
+
Copyright, 2026, by William T. Nelson.
|
|
8
9
|
|
|
9
10
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
11
|
of this software and associated documentation files (the "Software"), to deal
|
data/readme.md
CHANGED
|
@@ -14,17 +14,37 @@ Please see the [project documentation](https://socketry.github.io/async-pool/) f
|
|
|
14
14
|
|
|
15
15
|
Please see the [project releases](https://socketry.github.io/async-pool/releases/index) for all releases.
|
|
16
16
|
|
|
17
|
-
### v0.
|
|
17
|
+
### v0.12.0
|
|
18
|
+
|
|
19
|
+
- Use identity-based tracking for pooled resources and preserve insertion order when selecting available resources.
|
|
20
|
+
|
|
21
|
+
### v0.11.2
|
|
18
22
|
|
|
19
23
|
## Contributing
|
|
20
24
|
|
|
21
25
|
We welcome contributions to this project.
|
|
22
26
|
|
|
23
|
-
1. Fork
|
|
27
|
+
1. Fork the repository.
|
|
24
28
|
2. Create your feature branch (`git checkout -b my-new-feature`).
|
|
25
|
-
3. Commit your changes (`git commit -am 'Add some feature'`).
|
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature.'`).
|
|
26
30
|
4. Push to the branch (`git push origin my-new-feature`).
|
|
27
|
-
5. Create new
|
|
31
|
+
5. Create a new pull request.
|
|
32
|
+
|
|
33
|
+
### Running Tests
|
|
34
|
+
|
|
35
|
+
To run the test suite:
|
|
36
|
+
|
|
37
|
+
``` bash
|
|
38
|
+
$ bundle exec sus
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Making Releases
|
|
42
|
+
|
|
43
|
+
To make a new release:
|
|
44
|
+
|
|
45
|
+
``` bash
|
|
46
|
+
$ bundle exec bake gem:release:patch # or minor or major
|
|
47
|
+
```
|
|
28
48
|
|
|
29
49
|
### Developer Certificate of Origin
|
|
30
50
|
|
data/releases.md
CHANGED
data.tar.gz.sig
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
g�_r=GUwx:��]�<r1��W��ef4p�#
|
|
2
|
+
�B�UE b��6�ϵ_�!n�!�K0��X�x�W������|�����u�1�U�p�LL�����'[��,�$�!?��
|
|
3
|
+
�X��������#rq�U��Ci�5���߾!��ӏF���Rس�N?,�G��7�\�)(�4��=F�5���m�Z���B/7B�8h�&v~�]���Yw�.�K��s'(� �b�??�,�g�~�D�R[-K���#!�
|
|
4
|
+
Ҁ1��=%\F����H����٣h�"@����_߶Έ��ч�2�ϊv�dm"F7
|
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.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -9,6 +9,7 @@ authors:
|
|
|
9
9
|
- Olle Jonsson
|
|
10
10
|
- Simon Perepelitsa
|
|
11
11
|
- Thomas Morgan
|
|
12
|
+
- William T. Nelson
|
|
12
13
|
bindir: bin
|
|
13
14
|
cert_chain:
|
|
14
15
|
- |
|
|
@@ -72,6 +73,8 @@ homepage: https://github.com/socketry/async-pool
|
|
|
72
73
|
licenses:
|
|
73
74
|
- MIT
|
|
74
75
|
metadata:
|
|
76
|
+
bug_tracker_uri: https://github.com/socketry/async-pool/issues
|
|
77
|
+
changelog_uri: https://github.com/socketry/async-pool/blob/main/releases.md
|
|
75
78
|
documentation_uri: https://socketry.github.io/async-pool/
|
|
76
79
|
funding_uri: https://github.com/sponsors/ioquatix/
|
|
77
80
|
source_code_uri: https://github.com/socketry/async-pool.git
|
|
@@ -82,14 +85,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
82
85
|
requirements:
|
|
83
86
|
- - ">="
|
|
84
87
|
- !ruby/object:Gem::Version
|
|
85
|
-
version: '3.
|
|
88
|
+
version: '3.3'
|
|
86
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
90
|
requirements:
|
|
88
91
|
- - ">="
|
|
89
92
|
- !ruby/object:Gem::Version
|
|
90
93
|
version: '0'
|
|
91
94
|
requirements: []
|
|
92
|
-
rubygems_version:
|
|
95
|
+
rubygems_version: 4.0.10
|
|
93
96
|
specification_version: 4
|
|
94
97
|
summary: A singleplex and multiplex resource pool for implementing robust clients.
|
|
95
98
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|