async 2.29.1 → 2.31.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: f3ecf839913862d1e1638fd14c067e57b4e68a469bc8805d6dd4d568829ab02c
4
- data.tar.gz: 10a3624e0c564f7d895f77738e88b8a2e0b89ca58fd285488b32bf57509ff3de
3
+ metadata.gz: 2021787bfa001830a1a65e77ca0162349f4b7c21206077a8583f7cb81268a6b4
4
+ data.tar.gz: af5adae74c2b6e31df15e8885f7f5cad8f18090390d386c8d6373cebca5d1be7
5
5
  SHA512:
6
- metadata.gz: 4b3ad1290e807941399e29efe94faf04bbc721a4d59b06292abaac482acc27fac25834629a2869a343439594cd8f0576c01af3ccf9bc9f5661885f8fdbf3bcf1
7
- data.tar.gz: 89c92f9cf32ab403100ea4c00e3d93a2257aac2dd036473ecde04efb5182cffb2d91e76185b7d48f24f9ccceaf3e8dec6609549e96b72225012a964d5d93c207
6
+ metadata.gz: 27db90ffb96b0b179a311023e73f02837e668a81c7979406b1becf1278f2af8af0aebf24947748feac6b5ba9da0774073d0ae5925e747b7a3c0eb78803ef83c2
7
+ data.tar.gz: 14328112f76c82aa10aff761e23897dec82ae7512a6c5fd72a4f3708c9a828f2d53538a22e49abecfd9bdf30e243c63bb7f4c2feccd088daf208143a77d756c2
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ require_relative "clock"
7
+
8
+ # @namespace
9
+ module Async
10
+ # Represents a deadline timeout with decrementing remaining time.
11
+ # Includes an efficient representation for zero (non-blocking) timeouts.
12
+ # @public Since *Async v2.31*.
13
+ class Deadline
14
+ # Singleton module for immediate timeouts (zero or negative).
15
+ # Avoids object allocation for fast path (non-blocking) timeouts.
16
+ module Zero
17
+ # Check if the deadline has expired.
18
+ # @returns [Boolean] Always returns true since zero timeouts are immediately expired.
19
+ def self.expired?
20
+ true
21
+ end
22
+
23
+ # Get the remaining time.
24
+ # @returns [Integer] Always returns 0 since zero timeouts have no remaining time.
25
+ def self.remaining
26
+ 0
27
+ end
28
+ end
29
+
30
+ # Create a deadline for the given timeout.
31
+ # @parameter timeout [Numeric | Nil] The timeout duration, or nil for no timeout.
32
+ # @returns [Deadline | Nil] A deadline instance, Zero singleton, or nil.
33
+ def self.start(timeout)
34
+ if timeout.nil?
35
+ nil
36
+ elsif timeout <= 0
37
+ Zero
38
+ else
39
+ self.new(timeout)
40
+ end
41
+ end
42
+
43
+ # Create a new deadline with the specified remaining time.
44
+ # @parameter remaining [Numeric] The initial remaining time.
45
+ def initialize(remaining)
46
+ @remaining = remaining
47
+ @start = Clock.now
48
+ end
49
+
50
+ # Get the remaining time, updating internal state.
51
+ # Each call to this method advances the internal clock and reduces
52
+ # the remaining time by the elapsed duration since the last call.
53
+ # @returns [Numeric] The remaining time (may be negative if expired).
54
+ def remaining
55
+ now = Clock.now
56
+ delta = now - @start
57
+ @start = now
58
+
59
+ @remaining -= delta
60
+
61
+ return @remaining
62
+ end
63
+
64
+ # Check if the deadline has expired.
65
+ # @returns [Boolean] True if no time remains.
66
+ def expired?
67
+ self.remaining <= 0
68
+ end
69
+ end
70
+ end
@@ -39,8 +39,8 @@ module Async
39
39
  condition.signal
40
40
  end
41
41
 
42
- def wait_for_value(mutex)
43
- condition.wait(mutex)
42
+ def wait_for_value(mutex, timeout = nil)
43
+ condition.wait(mutex, timeout)
44
44
  return self.value
45
45
  end
46
46
 
@@ -55,6 +55,8 @@ module Async
55
55
  end
56
56
  end
57
57
 
58
+ private_constant :Waiter
59
+
58
60
  # Create a new priority queue.
59
61
  #
60
62
  # @parameter parent [Interface(:async) | Nil] The parent task to use for async operations.
@@ -81,6 +83,11 @@ module Async
81
83
  end
82
84
  end
83
85
 
86
+ # @returns [Boolean] Whether the queue is closed.
87
+ def closed?
88
+ @closed
89
+ end
90
+
84
91
  # @attribute [Array] The items in the queue.
85
92
  attr :items
86
93
 
@@ -153,13 +160,14 @@ module Async
153
160
 
154
161
  # Remove and return the next item from the queue.
155
162
  #
156
- # If the queue is empty, this method will block until an item is available.
163
+ # If the queue is empty, this method will block until an item is available or timeout expires.
157
164
  # Fibers are served in priority order, with higher priority fibers receiving
158
165
  # items first.
159
166
  #
160
167
  # @parameter priority [Numeric] The priority of this consumer (higher = served first).
161
- # @returns [Object] The next item in the queue.
162
- def dequeue(priority: 0)
168
+ # @parameter timeout [Numeric, nil] Maximum time to wait for an item. If nil, waits indefinitely. If 0, returns immediately.
169
+ # @returns [Object, nil] The next item in the queue, or nil if timeout expires.
170
+ def dequeue(priority: 0, timeout: nil)
163
171
  @mutex.synchronize do
164
172
  # If queue is closed and empty, return nil immediately:
165
173
  if @closed && @items.empty?
@@ -174,6 +182,9 @@ module Async
174
182
  end
175
183
  end
176
184
 
185
+ # Handle immediate timeout (non-blocking)
186
+ return nil if timeout == 0
187
+
177
188
  # Need to wait - create our own condition variable and add to waiting queue:
178
189
  sequence = @sequence
179
190
  @sequence += 1
@@ -185,7 +196,7 @@ module Async
185
196
  @waiting.push(waiter)
186
197
 
187
198
  # Wait for our specific condition variable to be signaled:
188
- return waiter.wait_for_value(@mutex)
199
+ return waiter.wait_for_value(@mutex, timeout)
189
200
  ensure
190
201
  waiter&.invalidate!
191
202
  end
@@ -195,8 +206,10 @@ module Async
195
206
  # Compatibility with {::Queue#pop}.
196
207
  #
197
208
  # @parameter priority [Numeric] The priority of this consumer.
198
- def pop(priority: 0)
199
- self.dequeue(priority: priority)
209
+ # @parameter timeout [Numeric, nil] Maximum time to wait for an item. If nil, waits indefinitely. If 0, returns immediately.
210
+ # @returns [Object, nil] The dequeued item, or nil if timeout expires.
211
+ def pop(priority: 0, timeout: nil)
212
+ self.dequeue(priority: priority, timeout: timeout)
200
213
  end
201
214
 
202
215
  # Process each item in the queue.
data/lib/async/queue.rb CHANGED
@@ -73,13 +73,17 @@ module Async
73
73
  end
74
74
 
75
75
  # Remove and return the next item from the queue.
76
- def dequeue
77
- @delegate.pop
76
+ # @parameter timeout [Numeric, nil] Maximum time to wait for an item. If nil, waits indefinitely. If 0, returns immediately.
77
+ # @returns [Object, nil] The dequeued item, or nil if timeout expires.
78
+ def dequeue(timeout: nil)
79
+ @delegate.pop(timeout: timeout)
78
80
  end
79
81
 
80
82
  # Compatibility with {::Queue#pop}.
81
- def pop(...)
82
- @delegate.pop(...)
83
+ # @parameter timeout [Numeric, nil] Maximum time to wait for an item. If nil, waits indefinitely. If 0, returns immediately.
84
+ # @returns [Object, nil] The dequeued item, or nil if timeout expires.
85
+ def pop(timeout: nil)
86
+ @delegate.pop(timeout: timeout)
83
87
  end
84
88
 
85
89
  # Process each item in the queue.
data/lib/async/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2017-2025, by Samuel Williams.
5
5
 
6
6
  module Async
7
- VERSION = "2.29.1"
7
+ VERSION = "2.31.0"
8
8
  end
data/readme.md CHANGED
@@ -35,6 +35,17 @@ Please see the [project documentation](https://socketry.github.io/async/) for mo
35
35
 
36
36
  Please see the [project releases](https://socketry.github.io/async/releases/index) for all releases.
37
37
 
38
+ ### v2.31.0
39
+
40
+ - Introduce `Async::Deadline` for precise timeout management in compound operations.
41
+
42
+ ### v2.30.0
43
+
44
+ - Add timeout support to `Async::Queue#dequeue` and `Async::Queue#pop` methods.
45
+ - Add timeout support to `Async::PriorityQueue#dequeue` and `Async::PriorityQueue#pop` methods.
46
+ - Add `closed?` method to `Async::PriorityQueue` for full queue interface compatibility.
47
+ - Support non-blocking operations using `timeout: 0` parameter.
48
+
38
49
  ### v2.29.0
39
50
 
40
51
  This release introduces thread-safety as a core concept of Async. Many core classes now have thread-safe guarantees, allowing them to be used safely across multiple threads.
@@ -74,23 +85,6 @@ This release introduces thread-safety as a core concept of Async. Many core clas
74
85
  - `Async::Task#stop` supports an optional `cause:` argument (that defaults to `$!`), which allows you to specify the cause (exception) for stopping the task.
75
86
  - Add thread-safety agent context.
76
87
 
77
- ### v2.26.0
78
-
79
- - `Async::Notification#signal` now returns `true` if a task was signaled, `false` otherwise, providing better feedback for notification operations.
80
- - `require "async/limited_queue"` is required to use `Async::LimitedQueue` without a deprecation warning. `Async::LimitedQueue` is not deprecated, but it's usage via `async/queue` is deprecated.
81
- - `Async::Task#sleep` is deprecated with no replacement.
82
- - `Async::Task.yield` is deprecated with no replacement.
83
- - `Async::Scheduler#async` is deprecated, use `Async{}`, `Sync{}` or `Async::Task#async` instead.
84
- - Agent context is now available, via the [`agent-context` gem](https://github.com/ioquatix/agent-context).
85
- - [`Async::Barrier` Improvements](https://socketry.github.io/async/releases/index#async::barrier-improvements)
86
- - [Introduce `Async::Queue#close`](https://socketry.github.io/async/releases/index#introduce-async::queue#close)
87
-
88
- ### v2.25.0
89
-
90
- - Added support for `io_select` hook in the fiber scheduler, allowing non-blocking `IO.select` operations. This enables better integration with code that uses `IO.select` for multiplexing IO operations.
91
- - [Use `IO::Event::WorkerPool` for Blocking Operations](https://socketry.github.io/async/releases/index#use-io::event::workerpool-for-blocking-operations)
92
- - [Better handling of `IO#close` using `fiber_interrupt`](https://socketry.github.io/async/releases/index#better-handling-of-io#close-using-fiber_interrupt)
93
-
94
88
  ## See Also
95
89
 
96
90
  - [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client/server.
data/releases.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Releases
2
2
 
3
+ ## v2.31.0
4
+
5
+ - Introduce `Async::Deadline` for precise timeout management in compound operations.
6
+
7
+ ## v2.30.0
8
+
9
+ - Add timeout support to `Async::Queue#dequeue` and `Async::Queue#pop` methods.
10
+ - Add timeout support to `Async::PriorityQueue#dequeue` and `Async::PriorityQueue#pop` methods.
11
+ - Add `closed?` method to `Async::PriorityQueue` for full queue interface compatibility.
12
+ - Support non-blocking operations using `timeout: 0` parameter.
13
+
3
14
  ## v2.29.0
4
15
 
5
16
  This release introduces thread-safety as a core concept of Async. Many core classes now have thread-safe guarantees, allowing them to be used safely across multiple threads.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.29.1
4
+ version: 2.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -38,6 +38,7 @@ authors:
38
38
  - Sokolov Yura
39
39
  - Stefan Wrobel
40
40
  - Trevor Turk
41
+ autorequire:
41
42
  bindir: bin
42
43
  cert_chain:
43
44
  - |
@@ -69,7 +70,7 @@ cert_chain:
69
70
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
70
71
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
71
72
  -----END CERTIFICATE-----
72
- date: 1980-01-02 00:00:00.000000000 Z
73
+ date: 2025-09-08 00:00:00.000000000 Z
73
74
  dependencies:
74
75
  - !ruby/object:Gem::Dependency
75
76
  name: console
@@ -141,6 +142,8 @@ dependencies:
141
142
  - - "~>"
142
143
  - !ruby/object:Gem::Version
143
144
  version: '0.18'
145
+ description:
146
+ email:
144
147
  executables: []
145
148
  extensions: []
146
149
  extra_rdoc_files: []
@@ -159,6 +162,7 @@ files:
159
162
  - lib/async/condition.md
160
163
  - lib/async/condition.rb
161
164
  - lib/async/console.rb
165
+ - lib/async/deadline.rb
162
166
  - lib/async/idler.rb
163
167
  - lib/async/limited_queue.rb
164
168
  - lib/async/list.rb
@@ -195,6 +199,7 @@ metadata:
195
199
  documentation_uri: https://socketry.github.io/async/
196
200
  funding_uri: https://github.com/sponsors/ioquatix/
197
201
  source_code_uri: https://github.com/socketry/async.git
202
+ post_install_message:
198
203
  rdoc_options: []
199
204
  require_paths:
200
205
  - lib
@@ -209,7 +214,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
214
  - !ruby/object:Gem::Version
210
215
  version: '0'
211
216
  requirements: []
212
- rubygems_version: 3.7.0.dev
217
+ rubygems_version: 3.5.22
218
+ signing_key:
213
219
  specification_version: 4
214
220
  summary: A concurrency framework for Ruby.
215
221
  test_files: []
metadata.gz.sig CHANGED
Binary file