atomic-ruby 0.15.5 → 0.16.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: 6022f081e7f3e4ce545c40989e5a644beea0697da5d840f645ae3764fbb80e4e
4
- data.tar.gz: 94b4312e55cfbda05127bde7ac74efd98da8708cb9835e718e7c02641f1d241a
3
+ metadata.gz: ecdfa4ed4bb185acac2d6ce288418318e23c1e4825fddff06d74a702d19d0d39
4
+ data.tar.gz: d2c935cb440869f1f622a30a585d71767ef57e3d08de78f332810e63acff1aa5
5
5
  SHA512:
6
- metadata.gz: bbcef6942791f3611e55c7c9806bd5daa4b71dd4bae4bedd255c0d1598e16c0ba50a19ae92423768fca04a4baafd80f464877f60960a7e43be0fc08ed2ffb3a3
7
- data.tar.gz: '0883a4a401963ad0db23713c6ae6917bec1c3bd1cd3bd8ecff069cc63c99b3000a914ee0c9345cd9f2495f88f0d6da6c35a51057b80a56877409ba19ce3c5e4f'
6
+ metadata.gz: 10e31be43b93f0d22de13ec3bea7f7d8bf411aa5282c5d36de2ee8da7693b968ab1aacbdc6c428317450670585bb857f0b8ecf657b71af6f18fcea9ab8c8c314
7
+ data.tar.gz: d99ed0322536e33b725a5ddda3202eced49bc71de567d6505079d3fbcd8b11b4df9d2216c834a5b0fa546105860eef3ccf0848d4455870992061991be6f772aa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.16.0] - 2026-10-18
4
+
5
+ - Add `AtomicThreadPool#wait_for_capacity`
6
+
3
7
  ## [0.15.5] - 2026-09-03
4
8
 
5
9
  - Adapt `AtomicThreadPool` scaling to workload pressure
data/README.md CHANGED
@@ -270,7 +270,7 @@ puts "Atomic Ruby Atomic Bank Account: #{results[2].real.round(6)} seconds"
270
270
 
271
271
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
272
272
  concurrent-ruby version: 1.3.8
273
- atomic-ruby version: 0.15.5
273
+ atomic-ruby version: 0.16.0
274
274
 
275
275
  Balances:
276
276
  Synchronized Bank Account Balance: 975
@@ -361,7 +361,7 @@ end
361
361
 
362
362
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
363
363
  concurrent-ruby version: 1.3.8
364
- atomic-ruby version: 0.15.5
364
+ atomic-ruby version: 0.16.0
365
365
 
366
366
  Warming up --------------------------------------
367
367
  Synchronized Boolean Toggle 165.000 i/100ms
@@ -444,7 +444,7 @@ end
444
444
  > bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_condition_variable_benchmark.rb
445
445
 
446
446
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
447
- atomic-ruby version: 0.15.5
447
+ atomic-ruby version: 0.16.0
448
448
 
449
449
  Warming up --------------------------------------
450
450
  Synchronized Condition Variable Wait/Signal 4.062k i/100ms
@@ -519,7 +519,7 @@ end
519
519
  > bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_queue_benchmark.rb
520
520
 
521
521
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
522
- atomic-ruby version: 0.15.5
522
+ atomic-ruby version: 0.16.0
523
523
 
524
524
  Warming up --------------------------------------
525
525
  Synchronized Queue Push/Pop 184.000 i/100ms
@@ -620,17 +620,17 @@ puts "Atomic Ruby Adaptive Thread Pool: #{adaptive_results[1].real.round(6)} sec
620
620
  ```
621
621
  > bundle exec rake clobber && bundle exec rake compile && bundle exec ruby examples/atomic_thread_pool_benchmark.rb
622
622
 
623
- ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
623
+ ruby version: ruby 4.0.7 (2026-09-15 revision 229531a6cf) +YJIT +PRISM [arm64-darwin23]
624
624
  concurrent-ruby version: 1.3.8
625
- atomic-ruby version: 0.15.5
625
+ atomic-ruby version: 0.16.0
626
626
 
627
627
  Fixed Pool Results:
628
- Concurrent Ruby Fixed Thread Pool: 5.05313 seconds
629
- Atomic Ruby Fixed Thread Pool: 4.753026 seconds
628
+ Concurrent Ruby Fixed Thread Pool: 5.147226 seconds
629
+ Atomic Ruby Fixed Thread Pool: 4.743301 seconds
630
630
 
631
631
  Adaptive Pool Results:
632
- Concurrent Ruby IO Thread Pool: 0.221072 seconds
633
- Atomic Ruby Adaptive Thread Pool: 0.233328 seconds
632
+ Concurrent Ruby IO Thread Pool: 0.217971 seconds
633
+ Atomic Ruby Adaptive Thread Pool: 0.227701 seconds
634
634
  ```
635
635
 
636
636
  </details>
@@ -684,7 +684,7 @@ puts "Atomic Ruby Atomic Count Down Latch: #{results[1].total.round(6)} CPU seco
684
684
 
685
685
  ruby version: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +YJIT +PRISM [arm64-darwin23]
686
686
  concurrent-ruby version: 1.3.8
687
- atomic-ruby version: 0.15.5
687
+ atomic-ruby version: 0.16.0
688
688
 
689
689
  Benchmark Results:
690
690
  Concurrent Ruby Count Down Latch: 0.000511 CPU seconds, 2.001465 elapsed seconds
@@ -118,6 +118,7 @@ module AtomicRuby
118
118
  @queue = AtomicQueue.new
119
119
  @shutdown = AtomicBoolean.new(false)
120
120
  @work_available = AtomicConditionVariable.new
121
+ @capacity_changed = AtomicConditionVariable.new
121
122
  @alive_thread_count = Atom.new(0)
122
123
  @active_thread_count = Atom.new(0)
123
124
  @threads = []
@@ -238,6 +239,25 @@ module AtomicRuby
238
239
  @active_thread_count.value
239
240
  end
240
241
 
242
+ # Blocks until the given block returns a truthy value, checking it again
243
+ # whenever a worker takes or finishes work.
244
+ #
245
+ # Useful for applying backpressure, such as holding off on accepting more
246
+ # work until the pool has capacity for it.
247
+ #
248
+ # @yieldreturn [untyped] Truthy to stop waiting, falsy to keep waiting
249
+ # @return [untyped] The first truthy value returned by the block
250
+ #
251
+ # @example Wait until no work is queued
252
+ # pool = AtomicThreadPool.new(size: 2)
253
+ # 5.times { pool << proc { sleep(0.1) } }
254
+ # pool.wait_for_capacity { pool.queue_length.zero? } #=> true
255
+ #
256
+ # @rbs () { () -> untyped } -> untyped
257
+ def wait_for_capacity(&block)
258
+ @capacity_changed.wait(&block)
259
+ end
260
+
241
261
  # Gracefully shuts down the thread pool.
242
262
  #
243
263
  # This method:
@@ -351,6 +371,7 @@ module AtomicRuby
351
371
  break if should_exit
352
372
 
353
373
  @active_thread_count.swap { |current_count| current_count + 1 }
374
+ @capacity_changed.broadcast unless @capacity_changed.waiter_count.zero?
354
375
  if temporary
355
376
  work_started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
356
377
  running_cpu_time_at_start = @thread_pool_monitor.snapshot[6]
@@ -368,6 +389,7 @@ module AtomicRuby
368
389
  ensure
369
390
  @thread_pool_monitor&.stop_work
370
391
  @active_thread_count.swap { |current_count| current_count - 1 }
392
+ @capacity_changed.broadcast unless @capacity_changed.waiter_count.zero?
371
393
  if temporary && !@queue.empty?
372
394
  elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - work_started_at
373
395
  running_cpu_time = @thread_pool_monitor.snapshot[6] - running_cpu_time_at_start
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AtomicRuby
4
- VERSION = "0.15.5"
4
+ VERSION = "0.16.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atomic-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.5
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Young
@@ -52,7 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  requirements: []
55
- rubygems_version: 4.0.16
55
+ rubygems_version: 4.0.20
56
56
  specification_version: 4
57
57
  summary: Atomic primitives for Ruby
58
58
  test_files: []