async 2.25.0 → 2.26.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: 44c11aa8f74922b9bc2ccce792fd3c419af4a3a261f97f2f2202e3d75a5bf8f5
4
- data.tar.gz: e2327b997b32a42e2ebfe9a4e4950d26a12ce698ce34a89d9fe1be94b0241b1f
3
+ metadata.gz: 9c593ddf06be9954e63b4f85eb8c0fe022be6cf1e241a37f86620a82fdf860b3
4
+ data.tar.gz: 023b1544a36d3bb8ff85f0b8cc3ccc0b4694ed3b0542ed7dafd02330f05ee663
5
5
  SHA512:
6
- metadata.gz: 20961f535e5368753dffdb760d9bddf0fcf55e5910e5f6c71dba28ebb0405221d9328a8bfe5ef4e688ead71b4b5c4bde3949ce1edfa013b06af7db57adfe6d7f
7
- data.tar.gz: d58c654852cd650978fa14fef7eaba00f4784137075960e5ad5b0b6b20ae3523912578b32b660f7d107df318cdd34945124e83231c4e574e336c5c4862a6c87c
6
+ metadata.gz: 65c3fee1ef33362307c4c74dd2451384de1e1747041ffd68cec0049465a317dada93083198254b905e89758a112800894436fe4cc8a2c713b0c0f5de1a36402e
7
+ data.tar.gz: a90fa15643b4a491599e95429c0d79da4363d0778455a50893ee9d6f34217ebd442bf99085f981807e024dfec561f545ea86d74e06f2874b34c1bd191a1b79fa
checksums.yaml.gz.sig CHANGED
Binary file
data/agent.md ADDED
@@ -0,0 +1,47 @@
1
+ # Agent
2
+
3
+ ## Context
4
+
5
+ This section provides links to documentation from installed packages. It is automatically generated and may be updated by running `bake agent:context:install`.
6
+
7
+ **Important:** Before performing any code, documentation, or analysis tasks, always read and apply the full content of any relevant documentation referenced in the following sections. These context files contain authoritative standards and best practices for documentation, code style, and project-specific workflows. **Do not proceed with any actions until you have read and incorporated the guidance from relevant context files.**
8
+
9
+ ### agent-context
10
+
11
+ Install and manage context files from Ruby gems.
12
+
13
+ #### [Usage Guide](.context/agent-context/usage.md)
14
+
15
+ `agent-context` is a tool that helps you discover and install contextual information from Ruby gems for AI agents. Gems can provide additional documentation, examples, and guidance in a `context/` ...
16
+
17
+ ### decode
18
+
19
+ Code analysis for documentation generation.
20
+
21
+ #### [Getting Started with Decode](.context/decode/getting-started.md)
22
+
23
+ The Decode gem provides programmatic access to Ruby code structure and metadata. It can parse Ruby files and extract definitions, comments, and documentation pragmas, enabling code analysis, docume...
24
+
25
+ #### [Documentation Coverage](.context/decode/coverage.md)
26
+
27
+ This guide explains how to test and monitor documentation coverage in your Ruby projects using the Decode gem's built-in bake tasks.
28
+
29
+ #### [Ruby Documentation](.context/decode/ruby-documentation.md)
30
+
31
+ This guide covers documentation practices and pragmas supported by the Decode gem for documenting Ruby code. These pragmas provide structured documentation that can be parsed and used to generate A...
32
+
33
+ ### sus
34
+
35
+ A fast and scalable test runner.
36
+
37
+ #### [Using Sus Testing Framework](.context/sus/usage.md)
38
+
39
+ Sus is a modern Ruby testing framework that provides a clean, BDD-style syntax for writing tests. It's designed to be fast, simple, and expressive.
40
+
41
+ #### [Mocking](.context/sus/mocking.md)
42
+
43
+ There are two types of mocking in sus: `receive` and `mock`. The `receive` matcher is a subset of full mocking and is used to set expectations on method calls, while `mock` can be used to replace m...
44
+
45
+ #### [Shared Test Behaviors and Fixtures](.context/sus/shared.md)
46
+
47
+ Sus provides shared test contexts which can be used to define common behaviours or tests that can be reused across one or more test files.
data/lib/async/barrier.md CHANGED
@@ -1,6 +1,5 @@
1
1
  A synchronization primitive, which allows one task to wait for a number of other tasks to complete. It can be used in conjunction with {Semaphore}.
2
2
 
3
-
4
3
  ## Example
5
4
 
6
5
  ~~~ ruby
data/lib/async/barrier.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "list"
7
7
  require_relative "task"
8
+ require_relative "queue"
8
9
 
9
10
  module Async
10
11
  # A general purpose synchronisation primitive, which allows one task to wait for a number of other tasks to complete. It can be used in conjunction with {Semaphore}.
@@ -16,6 +17,7 @@ module Async
16
17
  # @public Since *Async v1*.
17
18
  def initialize(parent: nil)
18
19
  @tasks = List.new
20
+ @finished = Queue.new
19
21
 
20
22
  @parent = parent
21
23
  end
@@ -41,11 +43,15 @@ module Async
41
43
  # Execute a child task and add it to the barrier.
42
44
  # @asynchronous Executes the given block concurrently.
43
45
  def async(*arguments, parent: (@parent or Task.current), **options, &block)
44
- task = parent.async(*arguments, **options, &block)
46
+ waiting = nil
45
47
 
46
- @tasks.append(TaskNode.new(task))
47
-
48
- return task
48
+ parent.async(*arguments, **options) do |task, *arguments|
49
+ waiting = TaskNode.new(task)
50
+ @tasks.append(waiting)
51
+ block.call(task, *arguments)
52
+ ensure
53
+ @finished.signal(waiting)
54
+ end
49
55
  end
50
56
 
51
57
  # Whether there are any tasks being held by the barrier.
@@ -55,14 +61,27 @@ module Async
55
61
  end
56
62
 
57
63
  # Wait for all tasks to complete by invoking {Task#wait} on each waiting task, which may raise an error. As long as the task has completed, it will be removed from the barrier.
64
+ #
65
+ # @yields {|task| ...} If a block is given, the unwaited task is yielded. You must invoke {Task#wait} yourself. In addition, you may `break` if you have captured enough results.
66
+ #
58
67
  # @asynchronous Will wait for tasks to finish executing.
59
68
  def wait
60
- @tasks.each do |waiting|
69
+ while !@tasks.empty?
70
+ # Wait for a task to finish (we get the task node):
71
+ return unless waiting = @finished.wait
72
+
73
+ # Remove the task as it is now finishing:
74
+ @tasks.remove?(waiting)
75
+
76
+ # Get the task:
61
77
  task = waiting.task
62
- begin
78
+
79
+ # If a block is given, the user can implement their own behaviour:
80
+ if block_given?
81
+ yield task
82
+ else
83
+ # Wait for it to either complete or raise an error:
63
84
  task.wait
64
- ensure
65
- @tasks.remove?(waiting) unless task.alive?
66
85
  end
67
86
  end
68
87
  end
@@ -73,6 +92,8 @@ module Async
73
92
  @tasks.each do |waiting|
74
93
  waiting.task.stop
75
94
  end
95
+
96
+ @finished.close
76
97
  end
77
98
  end
78
99
  end
@@ -42,6 +42,8 @@ module Async
42
42
 
43
43
  # @deprecated Replaced by {#waiting?}
44
44
  def empty?
45
+ warn("`Async::Condition#empty?` is deprecated, use `Async::Condition#waiting?` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
46
+
45
47
  @waiting.empty?
46
48
  end
47
49
 
@@ -5,3 +5,9 @@
5
5
 
6
6
  # The implementation lives in `queue.rb` but later we may move it here for better autoload/inference.
7
7
  require_relative "queue"
8
+
9
+ module Async
10
+ class LimitedQueue < Queue
11
+ singleton_class.remove_method(:new)
12
+ end
13
+ end
data/lib/async/list.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2024, by Samuel Williams.
4
+ # Copyright, 2022-2025, by Samuel Williams.
5
5
 
6
6
  module Async
7
7
  # A general doublely linked list. This is used internally by {Async::Barrier} and {Async::Condition} to manage child tasks.
@@ -18,6 +18,7 @@ module Async
18
18
  sprintf("#<%s:0x%x size=%d>", self.class.name, object_id, @size)
19
19
  end
20
20
 
21
+ # @returns [String] A short summary of the list.
21
22
  alias inspect to_s
22
23
 
23
24
  # Fast, safe, unbounded accumulation of children.
@@ -134,7 +135,7 @@ module Async
134
135
  return removed(node)
135
136
  end
136
137
 
137
- # @returns [Boolean] Returns true if the list is empty.
138
+ # @returns [Boolean] True if the list is empty.
138
139
  def empty?
139
140
  @size == 0
140
141
  end
@@ -238,6 +239,12 @@ module Async
238
239
  attr_accessor :head
239
240
  attr_accessor :tail
240
241
 
242
+ # @returns [String] A string representation of the node.
243
+ def to_s
244
+ sprintf("#<%s:0x%x>", self.class.name, object_id)
245
+ end
246
+
247
+ # @returns [String] A string representation of the node.
241
248
  alias inspect to_s
242
249
  end
243
250
 
data/lib/async/node.rb CHANGED
@@ -180,6 +180,7 @@ module Async
180
180
  "\#<#{self.description}>"
181
181
  end
182
182
 
183
+ # @returns [String] A description of the node.
183
184
  alias inspect to_s
184
185
 
185
186
  # Change the parent of this node.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2024, by Samuel Williams.
4
+ # Copyright, 2018-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "condition"
7
7
 
@@ -10,12 +10,14 @@ module Async
10
10
  # @public Since *Async v1*.
11
11
  class Notification < Condition
12
12
  # Signal to a given task that it should resume operations.
13
+ #
14
+ # @returns [Boolean] if a task was signalled.
13
15
  def signal(value = nil, task: Task.current)
14
- return if @waiting.empty?
16
+ return false if @waiting.empty?
15
17
 
16
18
  Fiber.scheduler.push Signal.new(self.exchange, value)
17
19
 
18
- return nil
20
+ return true
19
21
  end
20
22
 
21
23
  Signal = Struct.new(:waiting, :value) do
data/lib/async/queue.rb CHANGED
@@ -15,16 +15,31 @@ module Async
15
15
  #
16
16
  # @public Since *Async v1*.
17
17
  class Queue
18
+ # An error raised when trying to enqueue items to a closed queue.
19
+ # @public Since *Async v2.24*.
20
+ class ClosedError < RuntimeError
21
+ end
22
+
18
23
  # Create a new queue.
19
24
  #
20
25
  # @parameter parent [Interface(:async) | Nil] The parent task to use for async operations.
21
26
  # @parameter available [Notification] The notification to use for signaling when items are available.
22
27
  def initialize(parent: nil, available: Notification.new)
23
28
  @items = []
29
+ @closed = false
24
30
  @parent = parent
25
31
  @available = available
26
32
  end
27
33
 
34
+ # Close the queue, causing all waiting tasks to return `nil`. Any subsequent calls to {enqueue} will raise an exception.
35
+ def close
36
+ @closed = true
37
+
38
+ while @available.waiting?
39
+ @available.signal(nil)
40
+ end
41
+ end
42
+
28
43
  # @attribute [Array] The items in the queue.
29
44
  attr :items
30
45
 
@@ -40,6 +55,10 @@ module Async
40
55
 
41
56
  # Add an item to the queue.
42
57
  def push(item)
58
+ if @closed
59
+ raise ClosedError, "Cannot push items to a closed queue."
60
+ end
61
+
43
62
  @items << item
44
63
 
45
64
  @available.signal unless self.empty?
@@ -52,6 +71,10 @@ module Async
52
71
 
53
72
  # Add multiple items to the queue.
54
73
  def enqueue(*items)
74
+ if @closed
75
+ raise ClosedError, "Cannot enqueue items to a closed queue."
76
+ end
77
+
55
78
  @items.concat(items)
56
79
 
57
80
  @available.signal unless self.empty?
@@ -60,6 +83,10 @@ module Async
60
83
  # Remove and return the next item from the queue.
61
84
  def dequeue
62
85
  while @items.empty?
86
+ if @closed
87
+ return nil
88
+ end
89
+
63
90
  @available.wait
64
91
  end
65
92
 
@@ -106,6 +133,13 @@ module Async
106
133
  # A queue which limits the number of items that can be enqueued.
107
134
  # @public Since *Async v1*.
108
135
  class LimitedQueue < Queue
136
+ # @private This exists purely for emitting a warning.
137
+ def self.new(...)
138
+ warn("`require 'async/limited_queue'` to use `Async::LimitedQueue`.", uplevel: 1, category: :deprecated) if $VERBOSE
139
+
140
+ super
141
+ end
142
+
109
143
  # Create a new limited queue.
110
144
  #
111
145
  # @parameter limit [Integer] The maximum number of items that can be enqueued.
@@ -120,9 +154,19 @@ module Async
120
154
  # @attribute [Integer] The maximum number of items that can be enqueued.
121
155
  attr :limit
122
156
 
157
+ # Close the queue, causing all waiting tasks to return `nil`. Any subsequent calls to {enqueue} will raise an exception.
158
+ # Also signals all tasks waiting for the queue to be full.
159
+ def close
160
+ super
161
+
162
+ while @full.waiting?
163
+ @full.signal(nil)
164
+ end
165
+ end
166
+
123
167
  # @returns [Boolean] Whether trying to enqueue an item would block.
124
168
  def limited?
125
- @items.size >= @limit
169
+ !@closed && @items.size >= @limit
126
170
  end
127
171
 
128
172
  # Add an item to the queue.
@@ -149,6 +193,10 @@ module Async
149
193
  @full.wait
150
194
  end
151
195
 
196
+ if @closed
197
+ raise ClosedError, "Cannot enqueue items to a closed queue."
198
+ end
199
+
152
200
  available = @limit - @items.size
153
201
  @items.concat(items.shift(available))
154
202
 
data/lib/async/reactor.rb CHANGED
@@ -12,6 +12,8 @@ module Async
12
12
  class Reactor < Scheduler
13
13
  # @deprecated Replaced by {Kernel::Async}.
14
14
  def self.run(...)
15
+ warn("`Async::Reactor.run{}` is deprecated, use `Async{}` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
16
+
15
17
  Async(...)
16
18
  end
17
19
 
@@ -420,6 +420,9 @@ module Async
420
420
  # @asynchronous May be non-blocking.
421
421
  def io_select(...)
422
422
  Thread.new do
423
+ # Don't make unnecessary output, since we will propagate the exception:
424
+ Thread.current.report_on_exception = false
425
+
423
426
  ::IO.select(...)
424
427
  end.value
425
428
  end
@@ -580,7 +583,7 @@ module Async
580
583
  # @yields {|task| ...} Executed within the task.
581
584
  # @returns [Task] The task that was scheduled into the reactor.
582
585
  def async(*arguments, **options, &block)
583
- # warn "Async::Scheduler#async is deprecated. Use `run` or `Task#async` instead.", uplevel: 1, category: :deprecated
586
+ warn("Async::Scheduler#async is deprecated. Use `run` or `Task#async` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
584
587
 
585
588
  Kernel.raise ClosedError if @selector.nil?
586
589
 
@@ -591,6 +594,8 @@ module Async
591
594
  return task
592
595
  end
593
596
 
597
+ # Create a new fiber and return it without starting execution.
598
+ # @returns [Fiber] The fiber that was created.
594
599
  def fiber(...)
595
600
  return async(...).fiber
596
601
  end
data/lib/async/task.rb CHANGED
@@ -65,6 +65,8 @@ module Async
65
65
 
66
66
  # @deprecated With no replacement.
67
67
  def self.yield
68
+ warn("`Async::Task.yield` is deprecated with no replacement.", uplevel: 1, category: :deprecated) if $VERBOSE
69
+
68
70
  Fiber.scheduler.transfer
69
71
  end
70
72
 
@@ -134,6 +136,8 @@ module Async
134
136
 
135
137
  # @deprecated Prefer {Kernel#sleep} except when compatibility with `stable-v1` is required.
136
138
  def sleep(duration = nil)
139
+ Kernel.warn("`Async::Task#sleep` is deprecated, use `Kernel#sleep` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
140
+
137
141
  super
138
142
  end
139
143
 
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.25.0"
7
+ VERSION = "2.26.0"
8
8
  end
data/lib/async/waiter.rb CHANGED
@@ -6,12 +6,15 @@
6
6
 
7
7
  module Async
8
8
  # A composable synchronization primitive, which allows one task to wait for a number of other tasks to complete. It can be used in conjunction with {Semaphore} and/or {Barrier}.
9
+ # @deprecated `Async::Waiter` is deprecated, use `Async::Barrier` instead.
9
10
  class Waiter
10
11
  # Create a waiter instance.
11
12
  #
12
13
  # @parameter parent [Interface(:async) | Nil] The parent task to use for asynchronous operations.
13
14
  # @parameter finished [Async::Condition] The condition to signal when a task completes.
14
15
  def initialize(parent: nil, finished: Async::Condition.new)
16
+ warn("`Async::Waiter` is deprecated, use `Async::Barrier` instead.", uplevel: 1, category: :deprecated) if $VERBOSE
17
+
15
18
  @finished = finished
16
19
  @done = []
17
20
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2024, by Samuel Williams.
4
+ # Copyright, 2024-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "../../../async/barrier"
7
7
  require "traces/provider"
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.26.0
39
+
40
+ - `Async::Notification#signal` now returns `true` if a task was signaled, `false` otherwise, providing better feedback for notification operations.
41
+ - `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.
42
+ - `Async::Task#sleep` is deprecated with no replacement.
43
+ - `Async::Task.yield` is deprecated with no replacement.
44
+ - `Async::Scheduler#async` is deprecated, use `Async{}`, `Sync{}` or `Async::Task#async` instead.
45
+ - Agent context is now available, via the [`agent-context` gem](https://github.com/ioquatix/agent-context).
46
+ - [`Async::Barrier` Improvements](https://socketry.github.io/async/releases/index#async::barrier-improvements)
47
+ - [Introduce `Async::Queue#close`](https://socketry.github.io/async/releases/index#introduce-async::queue#close)
48
+
38
49
  ### v2.25.0
39
50
 
40
51
  - 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.
@@ -62,7 +73,7 @@ Please see the [project releases](https://socketry.github.io/async/releases/inde
62
73
 
63
74
  ### v2.19.0
64
75
 
65
- - [Async::Scheduler Debugging](https://socketry.github.io/async/releases/index#async::scheduler-debugging)
76
+ - [`Async::Scheduler` Debugging](https://socketry.github.io/async/releases/index#async::scheduler-debugging)
66
77
  - [Console Shims](https://socketry.github.io/async/releases/index#console-shims)
67
78
 
68
79
  ### v2.18.0
data/releases.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # Releases
2
2
 
3
+ ## v2.26.0
4
+
5
+ - `Async::Notification#signal` now returns `true` if a task was signaled, `false` otherwise, providing better feedback for notification operations.
6
+ - `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.
7
+ - `Async::Task#sleep` is deprecated with no replacement.
8
+ - `Async::Task.yield` is deprecated with no replacement.
9
+ - `Async::Scheduler#async` is deprecated, use `Async{}`, `Sync{}` or `Async::Task#async` instead.
10
+ - Agent context is now available, via the [`agent-context` gem](https://github.com/ioquatix/agent-context).
11
+
12
+ ### `Async::Barrier` Improvements
13
+
14
+ `Async::Barrier` now provides more flexible and predictable behavior for waiting on task completion:
15
+
16
+ - **Completion-order waiting**: `barrier.wait` now processes tasks in the order they complete rather than the order they were created. This provides more predictable behavior when tasks have different execution times.
17
+ - **Block-based waiting**: `barrier.wait` now accepts an optional block that yields each task as it completes, allowing for custom handling of individual tasks:
18
+
19
+ <!-- end list -->
20
+
21
+ ``` ruby
22
+ barrier = Async::Barrier.new
23
+
24
+ # Start several tasks
25
+ 3.times do |i|
26
+ barrier.async do |task|
27
+ sleep(rand * 0.1) # Random completion time
28
+ "result_#{i}"
29
+ end
30
+ end
31
+
32
+ # Wait for all tasks, processing them as they complete
33
+ barrier.wait do |task|
34
+ result = task.wait
35
+ puts "Task completed with: #{result}"
36
+ end
37
+ ```
38
+
39
+ - **Partial completion support**: The new block-based interface allows you to wait for only the first N tasks to complete:
40
+
41
+ <!-- end list -->
42
+
43
+ ``` ruby
44
+ # Wait for only the first 3 tasks to complete
45
+ count = 0
46
+ barrier.wait do |task|
47
+ task.wait
48
+ count += 1
49
+ break if count >= 3
50
+ end
51
+ ```
52
+
53
+ This makes `Async::Barrier` a superset of `Async::Waiter` functionality, providing more flexible task coordination patterns, and therrefore, `Async::Waiter` is now deprecated.
54
+
55
+ ### Introduce `Async::Queue#close`
56
+
57
+ `Async::Queue` and `Async::LimitedQueue` can now be closed, which provides better resource management and error handling:
58
+
59
+ - **New `close` method**: Both queue types now have a `close` method that prevents further items from being added and signals any waiting tasks.
60
+ - **Consistent error handling**: All queue modification methods (`push`, `enqueue`, `<<`) now raise `Async::Queue::ClosedError` when called on a closed queue.
61
+ - **Waiting task signaling**: When a queue is closed, any tasks waiting on `dequeue` (for regular queues) or `enqueue` (for limited queues) are properly signaled and can complete.
62
+
63
+ <!-- end list -->
64
+
65
+ ``` ruby
66
+ queue = Async::Queue.new
67
+
68
+ # Start a task waiting for items:
69
+ waiting_task = Async do
70
+ queue.dequeue
71
+ end
72
+
73
+ # Close the queue - this signals the waiting task
74
+ queue.close
75
+
76
+ # These will raise Async::Queue::ClosedError
77
+ queue.push(:item) # => raises ClosedError
78
+ queue.enqueue(:item) # => raises ClosedError
79
+ queue << :item # => raises ClosedError
80
+
81
+ # Dequeue returns nil when closed and empty
82
+ queue.dequeue # => nil
83
+ ```
84
+
3
85
  ## v2.25.0
4
86
 
5
87
  - 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.
@@ -34,7 +116,7 @@ end
34
116
 
35
117
  ### Flexible Timeouts
36
118
 
37
- When {ruby Async::Scheduler\#with\_timeout} is invoked with a block, it can receive a {ruby Async::Timeout} instance. This allows you to adjust or cancel the timeout while the block is executing. This is useful for long-running tasks that may need to adjust their timeout based on external factors.
119
+ When `Async::Scheduler#with_timeout` is invoked with a block, it can receive a `Async::Timeout` instance. This allows you to adjust or cancel the timeout while the block is executing. This is useful for long-running tasks that may need to adjust their timeout based on external factors.
38
120
 
39
121
  ``` ruby
40
122
  Async do
@@ -108,7 +190,7 @@ To take advantage of this feature, you will need to introduce your own `config/t
108
190
 
109
191
  ## v2.19.0
110
192
 
111
- ### Async::Scheduler Debugging
193
+ ### `Async::Scheduler` Debugging
112
194
 
113
195
  Occasionally on issues, I encounter people asking for help and I need more information. Pressing Ctrl-C to exit a hung program is common, but it usually doesn't provide enough information to diagnose the problem. Setting the `CONSOLE_LEVEL=debug` environment variable will now print additional information about the scheduler when you interrupt it, including a backtrace of the current tasks.
114
196
 
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.25.0
4
+ version: 2.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -10,6 +10,7 @@ authors:
10
10
  - Olle Jonsson
11
11
  - Patrik Wenger
12
12
  - Devin Christensen
13
+ - Shopify Inc.
13
14
  - Emil Tin
14
15
  - Jamie McCarthy
15
16
  - Kent Gruber
@@ -32,7 +33,6 @@ authors:
32
33
  - Salim Semaoune
33
34
  - Shannon Skipper
34
35
  - Shigeru Nakajima
35
- - Shopify Inc.
36
36
  - Sokolov Yura
37
37
  - Stefan Wrobel
38
38
  - Trevor Turk
@@ -103,14 +103,14 @@ dependencies:
103
103
  requirements:
104
104
  - - "~>"
105
105
  - !ruby/object:Gem::Version
106
- version: '1.11'
106
+ version: '1.12'
107
107
  type: :runtime
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
110
110
  requirements:
111
111
  - - "~>"
112
112
  - !ruby/object:Gem::Version
113
- version: '1.11'
113
+ version: '1.12'
114
114
  - !ruby/object:Gem::Dependency
115
115
  name: metrics
116
116
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +143,7 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
+ - agent.md
146
147
  - lib/async.rb
147
148
  - lib/async/barrier.md
148
149
  - lib/async/barrier.rb
@@ -165,7 +166,6 @@ files:
165
166
  - lib/async/timeout.rb
166
167
  - lib/async/variable.rb
167
168
  - lib/async/version.rb
168
- - lib/async/waiter.md
169
169
  - lib/async/waiter.rb
170
170
  - lib/kernel/async.rb
171
171
  - lib/kernel/sync.rb
metadata.gz.sig CHANGED
Binary file
data/lib/async/waiter.md DELETED
@@ -1,50 +0,0 @@
1
- A synchronization primitive, which allows you to wait for tasks to complete in order of completion. This is useful for implementing a task pool, where you want to wait for the first task to complete, and then cancel the rest.
2
-
3
- If you try to wait for more things than you have added, you will deadlock.
4
-
5
- ## Example
6
-
7
- ~~~ ruby
8
- require 'async'
9
- require 'async/semaphore'
10
- require 'async/barrier'
11
- require 'async/waiter'
12
-
13
- Sync do
14
- barrier = Async::Barrier.new
15
- waiter = Async::Waiter.new(parent: barrier)
16
- semaphore = Async::Semaphore.new(2, parent: waiter)
17
-
18
- # Sleep sort the numbers:
19
- generator = Async do
20
- while true
21
- semaphore.async do |task|
22
- number = rand(1..10)
23
- sleep(number)
24
- end
25
- end
26
- end
27
-
28
- numbers = []
29
-
30
- 4.times do
31
- # Wait for all the numbers to be sorted:
32
- numbers << waiter.wait
33
- end
34
-
35
- # Don't generate any more numbers:
36
- generator.stop
37
-
38
- # Stop all tasks which we don't care about:
39
- barrier.stop
40
-
41
- Console.info("Smallest", numbers)
42
- end
43
- ~~~
44
-
45
- ### Output
46
-
47
- ~~~
48
- 0.0s info: Smallest
49
- | [3, 3, 1, 2]
50
- ~~~