async-pool 0.11.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e4fe0a9bc65859c5bcb987643f591473236e1fdb2b296c9d73dc9750c01b44ff
4
- data.tar.gz: 116b1ec100edce9d7bbf85fe57a41d7f7059ed495eca17c8d96940a6c10e7724
3
+ metadata.gz: 8261d789df6f1e5666e9994a6b977a9a51f7c196701fffebe2f26eca28aab213
4
+ data.tar.gz: 9db4443e7e225ed235c8700c2a89292bced23af536abf5d5a625520ccc470c5f
5
5
  SHA512:
6
- metadata.gz: c17cc32005753a5f3141aa4a198c5a1b826a212c44f05a382951561bd3b274aaa66e6f0d8f77e21bd613b42f4ab1a6a0d51f9463abd4ecc33f42a5b1e46642b8
7
- data.tar.gz: 326fdcd55c875d840d02d1d9fe73082edb70d83361a4a2e1cde34331ded7b3bb184a436ec8907e3c0065c3444554a56eaa89817dd25ceb2936fbf3ff96b23ada
6
+ metadata.gz: e570ea6d402c540b87f604e84b5df47744a69d6eb99f423069b5cae560e6f8e8cd75102dc7e6c9c8514671099a00cd7596a6c2f4a0ab551857684b3cf27f2c02
7
+ data.tar.gz: 34c158ab5216a2c6a8c9fc930f6f0042fc19b05a71fe3659e4ebd06dc91094effb18c8c36c1c01c160d32d2cc306a6957496c6bf9d3f78553e8cfe5dbf939a0d
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2025, by Samuel Williams.
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.
@@ -12,6 +12,7 @@ require "console/logger"
12
12
  require "async"
13
13
  require "async/semaphore"
14
14
 
15
+ require "set"
15
16
  require "thread"
16
17
 
17
18
  module Async
@@ -41,12 +42,12 @@ module Async
41
42
 
42
43
  @tags = tags
43
44
 
44
- # All available resources:
45
- @resources = {}
45
+ # All allocated resources. Each resource is tracked by identity, irrespective of any value equality it may define:
46
+ @resources = {}.compare_by_identity
46
47
 
47
- # Resources which may be available to be acquired:
48
- # This list may contain false positives, or resources which were okay but have since entered a state which is unusuable.
49
- @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
50
51
 
51
52
  # Used to signal when a resource has been released:
52
53
  @mutex = Thread::Mutex.new
@@ -166,16 +167,31 @@ module Async
166
167
 
167
168
  # Make the resource resources and let waiting tasks know that there is something resources.
168
169
  def release(resource)
169
- processed = false
170
+ unless usage = decrement_usage(resource)
171
+ return false
172
+ end
170
173
 
171
- # A resource that is not good should also not be reusable.
172
174
  if resource.reusable?
173
- processed = reuse(resource)
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
174
185
  end
175
186
 
187
+ @mutex.synchronize{@condition.broadcast}
188
+
176
189
  # @policy.released(self, resource)
190
+
191
+ resource = nil
192
+ return true
177
193
  ensure
178
- retire(resource) unless processed
194
+ retire(resource) if resource
179
195
  end
180
196
 
181
197
  # Drain the pool, closing all resources.
@@ -282,31 +298,6 @@ module Async
282
298
  # @resources.count{|resource, usage| usage == 0}
283
299
  # end
284
300
 
285
- def reuse(resource)
286
- Console.debug(self){"Reuse #{resource}"}
287
-
288
- usage = @resources[resource]
289
-
290
- if usage.nil?
291
- return false
292
- end
293
-
294
- if usage.zero?
295
- raise "Trying to reuse unacquired resource: #{resource}!"
296
- end
297
-
298
- # If the resource was fully utilized, it now becomes available:
299
- if usage == resource.concurrency
300
- @available.push(resource)
301
- end
302
-
303
- @resources[resource] = usage - 1
304
-
305
- @mutex.synchronize{@condition.broadcast}
306
-
307
- return true
308
- end
309
-
310
301
  def wait_for_resource
311
302
  # If we fail to create a resource (below), we will end up waiting for one to become resources.
312
303
  until resource = available_resource
@@ -326,7 +317,7 @@ module Async
326
317
 
327
318
  # Make the resource available if it can be used multiple times:
328
319
  if resource.concurrency > 1
329
- @available.push(resource)
320
+ @available.add(resource)
330
321
  end
331
322
  end
332
323
 
@@ -345,12 +336,23 @@ module Async
345
336
 
346
337
  return resource
347
338
  rescue Exception
348
- reuse(resource) if resource
339
+ release(resource) if resource
349
340
  raise
350
341
  end
351
342
 
352
343
  private
353
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
+
354
356
  # Acquire an existing resource with zero usage.
355
357
  # If there are resources that are in use, wait until they are released.
356
358
  def acquire_existing_resource
@@ -367,24 +369,24 @@ module Async
367
369
  end
368
370
 
369
371
  def acquire_or_create_resource
370
- while resource = @available.last
372
+ while resource = @available.first
371
373
  if usage = @resources[resource] and usage < resource.concurrency
372
374
  if resource.viable?
373
375
  usage = (@resources[resource] += 1)
374
376
 
375
377
  if usage == resource.concurrency
376
378
  # The resource is used up to it's limit:
377
- @available.pop
379
+ @available.delete(resource)
378
380
  end
379
381
 
380
382
  return resource
381
383
  else
382
- retire(resource)
383
- @available.pop
384
+ @available.delete(resource)
385
+ retire(resource) if usage.zero?
384
386
  end
385
387
  else
386
388
  # The resource has been removed already, so skip it and remove it from the availability list.
387
- @available.pop
389
+ @available.delete(resource)
388
390
  end
389
391
  end
390
392
 
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2025, by Samuel Williams.
4
+ # Copyright, 2019-2026, by Samuel Williams.
5
5
 
6
6
  module Async
7
7
  module Pool
8
- VERSION = "0.11.2"
8
+ VERSION = "0.12.0"
9
9
  end
10
10
  end
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.12.0
18
+
19
+ - Use identity-based tracking for pooled resources and preserve insertion order when selecting available resources.
20
+
17
21
  ### v0.11.2
18
22
 
19
23
  ## Contributing
20
24
 
21
25
  We welcome contributions to this project.
22
26
 
23
- 1. Fork it.
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 Pull Request.
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
@@ -1,3 +1,7 @@
1
1
  # Releases
2
2
 
3
+ ## v0.12.0
4
+
5
+ - Use identity-based tracking for pooled resources and preserve insertion order when selecting available resources.
6
+
3
7
  ## v0.11.2
data.tar.gz.sig CHANGED
@@ -1,4 +1,4 @@
1
- _
2
- �!_ ����� /b���S�+v����H��m>���)�[p/븇]�=2}׍�)5N��{yH���N���;�.�{+� S֛'���i���(h_�����(n���j�����og�.��1�5�>��^��ёu{�ĺ2�<@�:Zڙ��4��(u1{F 2��*
3
- r�U�|6
4
- �X��0�
1
+ g_r=GUwx:��]�<r1��W��ef4p�#׫
2
+ B�UE b��6�ϵ_�!n�!�K0��XxW������|�����u�1�U�pLL�����'[��,�$�!?��
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.11.2
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -73,6 +73,8 @@ homepage: https://github.com/socketry/async-pool
73
73
  licenses:
74
74
  - MIT
75
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
76
78
  documentation_uri: https://socketry.github.io/async-pool/
77
79
  funding_uri: https://github.com/sponsors/ioquatix/
78
80
  source_code_uri: https://github.com/socketry/async-pool.git
@@ -83,14 +85,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
85
  requirements:
84
86
  - - ">="
85
87
  - !ruby/object:Gem::Version
86
- version: '3.2'
88
+ version: '3.3'
87
89
  required_rubygems_version: !ruby/object:Gem::Requirement
88
90
  requirements:
89
91
  - - ">="
90
92
  - !ruby/object:Gem::Version
91
93
  version: '0'
92
94
  requirements: []
93
- rubygems_version: 4.0.3
95
+ rubygems_version: 4.0.10
94
96
  specification_version: 4
95
97
  summary: A singleplex and multiplex resource pool for implementing robust clients.
96
98
  test_files: []
metadata.gz.sig CHANGED
Binary file