async 2.14.2 → 2.23.1

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: 12cf95e2d70376d5634d24377bb7d3d3974f14f20227fc33450fb103b17f5783
4
- data.tar.gz: e0c89541d8d039ec1672b68ef1ae90a86a00c065f6143769734bcbf7cc01d7de
3
+ metadata.gz: 36ac96ecf26e32e4804f8e89909dcb7b5f8cdfbed24a4da1a189d027586bd0b1
4
+ data.tar.gz: 35fb378abd8183a2a4950a2b57fd4ba6360c740b51a12ff3e67af5a2c443583c
5
5
  SHA512:
6
- metadata.gz: cec85cadb861dd14ed374930963e94785e066b8584537e2ef0cc28d8a804372bcf7895f9836d436bd72e20d3f4e0027820ea005dff60120f3d0b66192571e82a
7
- data.tar.gz: f11f62065e7fb9072f06b26514e98c33b6aac2988a485ebaf814792a68abe18711f9842187fcfa66282c8ce0290a1064c575a6d1f8cc5a18269f85f82886fc04
6
+ metadata.gz: 5ff90e092ac86b1dd3e5991e48d44d2b6a9abaa1b72d785d3e9419630f3f8fadd241ab21837bbd5ddd4038792e3ac970bf2aa4b2f67f5a473d4be1caa067f1d5
7
+ data.tar.gz: 5b71b8eae39aee81b3918f1012c76a4306529292626bf6dc95e79ecebcfa53cda304840655eee56c3392b5a912478ff3178ab4624a2f519ad02d6ce70098f1e2
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/async/barrier.md CHANGED
@@ -18,7 +18,7 @@ Sync do
18
18
  # Sleep sort the numbers:
19
19
  numbers.each do |number|
20
20
  barrier.async do |task|
21
- task.sleep(number)
21
+ sleep(number)
22
22
  sorted << number
23
23
  end
24
24
  end
data/lib/async/barrier.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2022, by Samuel Williams.
4
+ # Copyright, 2019-2024, by Samuel Williams.
5
5
 
6
- require_relative 'list'
7
- require_relative 'task'
6
+ require_relative "list"
7
+ require_relative "task"
8
8
 
9
9
  module Async
10
10
  # 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}.
11
11
  #
12
- # @public Since `stable-v1`.
12
+ # @public Since *Async v1*.
13
13
  class Barrier
14
14
  # Initialize the barrier.
15
15
  # @parameter parent [Task | Semaphore | Nil] The parent for holding any children tasks.
16
- # @public Since `stable-v1`.
16
+ # @public Since *Async v1*.
17
17
  def initialize(parent: nil)
18
18
  @tasks = List.new
19
19
 
data/lib/async/clock.rb CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  module Async
7
7
  # A convenient wrapper around the internal monotonic clock.
8
- # @public Since `stable-v1`.
8
+ # @public Since *Async v1*.
9
9
  class Clock
10
10
  # Get the current elapsed monotonic time.
11
11
  def self.now
@@ -61,5 +61,14 @@ module Async
61
61
 
62
62
  return total
63
63
  end
64
+
65
+ # Reset the total elapsed time. If the clock is currently running, reset the start time to now.
66
+ def reset!
67
+ @total = 0
68
+
69
+ if @started
70
+ @started = Clock.now
71
+ end
72
+ end
64
73
  end
65
74
  end
@@ -15,7 +15,7 @@ Sync do
15
15
  end
16
16
 
17
17
  Async do |task|
18
- task.sleep(1)
18
+ sleep(1)
19
19
  Console.info "Signalling condition..."
20
20
  condition.signal("Hello World")
21
21
  end
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2017-2022, by Samuel Williams.
4
+ # Copyright, 2017-2024, by Samuel Williams.
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
 
7
- require 'fiber'
8
- require_relative 'list'
7
+ require "fiber"
8
+ require_relative "list"
9
9
 
10
10
  module Async
11
11
  # A synchronization primitive, which allows fibers to wait until a particular condition is (edge) triggered.
12
- # @public Since `stable-v1`.
12
+ # @public Since *Async v1*.
13
13
  class Condition
14
14
  # Create a new condition.
15
15
  def initialize
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ module Async
7
+ # Shims for the console gem, redirecting warnings and above to `Kernel#warn`.
8
+ #
9
+ # If you require this file, the `async` library will not depend on the `console` gem.
10
+ #
11
+ # That includes any gems that sit within the `Async` namespace.
12
+ #
13
+ # This is an experimental feature.
14
+ module Console
15
+ # Log a message at the debug level. The shim is silent.
16
+ def self.debug(...)
17
+ end
18
+
19
+ # Log a message at the info level. The shim is silent.
20
+ def self.info(...)
21
+ end
22
+
23
+ # Log a message at the warn level. The shim redirects to `Kernel#warn`.
24
+ def self.warn(*arguments, exception: nil, **options)
25
+ if exception
26
+ super(*arguments, exception.full_message, **options)
27
+ else
28
+ super(*arguments, **options)
29
+ end
30
+ end
31
+
32
+ # Log a message at the error level. The shim redirects to `Kernel#warn`.
33
+ def self.error(...)
34
+ self.warn(...)
35
+ end
36
+
37
+ # Log a message at the fatal level. The shim redirects to `Kernel#warn`.
38
+ def self.fatal(...)
39
+ self.warn(...)
40
+ end
41
+ end
42
+ end
data/lib/async/idler.rb CHANGED
@@ -7,7 +7,8 @@ module Async
7
7
  # A load balancing mechanism that can be used process work when the system is idle.
8
8
  class Idler
9
9
  # Create a new idler.
10
- # @public Since `stable-v2`.
10
+ #
11
+ # @public Since *Async v2*.
11
12
  #
12
13
  # @parameter maximum_load [Numeric] The maximum load before we start shedding work.
13
14
  # @parameter backoff [Numeric] The initial backoff time, used for delaying work.
@@ -41,7 +42,8 @@ module Async
41
42
  backoff = nil
42
43
 
43
44
  while true
44
- load = scheduler.load
45
+ load = scheduler.load
46
+
45
47
  break if load < @maximum_load
46
48
 
47
49
  if backoff
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2024, by Samuel Williams.
5
+
6
+ # The implementation lives in `queue.rb` but later we may move it here for better autoload/inference.
7
+ require_relative "queue"
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, by Samuel Williams.
4
+ # Copyright, 2022-2024, 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.
data/lib/async/node.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2017-2023, by Samuel Williams.
4
+ # Copyright, 2017-2024, by Samuel Williams.
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
  # Copyright, 2022, by Shannon Skipper.
7
7
 
8
- require 'fiber/annotation'
8
+ require "fiber/annotation"
9
9
 
10
- require_relative 'list'
10
+ require_relative "list"
11
11
 
12
12
  module Async
13
13
  # A list of children tasks.
@@ -34,6 +34,19 @@ module Async
34
34
  empty?
35
35
  end
36
36
 
37
+ # Adjust the number of transient children, assuming it has changed.
38
+ #
39
+ # Despite being public, this is not intended to be called directly. It is used internally by {Node#transient=}.
40
+ #
41
+ # @parameter transient [Boolean] Whether to increment or decrement the transient count.
42
+ def adjust_transient_count(transient)
43
+ if transient
44
+ @transient_count += 1
45
+ else
46
+ @transient_count -= 1
47
+ end
48
+ end
49
+
37
50
  private
38
51
 
39
52
  def added(node)
@@ -110,6 +123,19 @@ module Async
110
123
  @transient
111
124
  end
112
125
 
126
+ # Change the transient state of the node.
127
+ #
128
+ # A transient node is not considered when determining if a node is finished, and propagates up if the parent is consumed.
129
+ #
130
+ # @parameter value [Boolean] Whether the node is transient.
131
+ def transient=(value)
132
+ if @transient != value
133
+ @transient = value
134
+
135
+ @parent&.children&.adjust_transient_count(value)
136
+ end
137
+ end
138
+
113
139
  # Annotate the node with a description.
114
140
  #
115
141
  # @parameter annotation [String] The description to annotate the node with.
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2022, by Samuel Williams.
4
+ # Copyright, 2018-2024, by Samuel Williams.
5
5
 
6
- require_relative 'condition'
6
+ require_relative "condition"
7
7
 
8
8
  module Async
9
9
  # A synchronization primitive, which allows fibers to wait until a notification is received. Does not block the task which signals the notification. Waiting tasks are resumed on next iteration of the reactor.
10
- # @public Since `stable-v1`.
10
+ # @public Since *Async v1*.
11
11
  class Notification < Condition
12
12
  # Signal to a given task that it should resume operations.
13
13
  def signal(value = nil, task: Task.current)
data/lib/async/queue.rb CHANGED
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2018-2022, by Samuel Williams.
4
+ # Copyright, 2018-2024, by Samuel Williams.
5
5
  # Copyright, 2019, by Ryan Musgrave.
6
6
  # Copyright, 2020-2022, by Bruno Sutic.
7
7
 
8
- require_relative 'notification'
8
+ require_relative "notification"
9
9
 
10
10
  module Async
11
11
  # A queue which allows items to be processed in order.
12
12
  #
13
13
  # It has a compatible interface with {Notification} and {Condition}, except that it's multi-value.
14
14
  #
15
- # @public Since `stable-v1`.
15
+ # @public Since *Async v1*.
16
16
  class Queue
17
17
  # Create a new queue.
18
18
  #
@@ -38,12 +38,17 @@ module Async
38
38
  end
39
39
 
40
40
  # Add an item to the queue.
41
- def <<(item)
41
+ def push(item)
42
42
  @items << item
43
43
 
44
44
  @available.signal unless self.empty?
45
45
  end
46
46
 
47
+ # Compatibility with {::Queue#push}.
48
+ def <<(item)
49
+ self.push(item)
50
+ end
51
+
47
52
  # Add multiple items to the queue.
48
53
  def enqueue(*items)
49
54
  @items.concat(items)
@@ -60,6 +65,11 @@ module Async
60
65
  @items.shift
61
66
  end
62
67
 
68
+ # Compatibility with {::Queue#pop}.
69
+ def pop
70
+ self.dequeue
71
+ end
72
+
63
73
  # Process each item in the queue.
64
74
  #
65
75
  # @asynchronous Executes the given block concurrently for each item.
@@ -82,7 +92,7 @@ module Async
82
92
  end
83
93
 
84
94
  # Signal the queue with a value, the same as {#enqueue}.
85
- def signal(value)
95
+ def signal(value = nil)
86
96
  self.enqueue(value)
87
97
  end
88
98
 
@@ -93,7 +103,7 @@ module Async
93
103
  end
94
104
 
95
105
  # A queue which limits the number of items that can be enqueued.
96
- # @public Since `stable-v1`.
106
+ # @public Since *Async v1*.
97
107
  class LimitedQueue < Queue
98
108
  # Create a new limited queue.
99
109
  #
@@ -119,7 +129,7 @@ module Async
119
129
  # If the queue is full, this method will block until there is space available.
120
130
  #
121
131
  # @parameter item [Object] The item to add to the queue.
122
- def <<(item)
132
+ def push(item)
123
133
  while limited?
124
134
  @full.wait
125
135
  end
data/lib/async/reactor.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2017-2022, by Samuel Williams.
4
+ # Copyright, 2017-2024, by Samuel Williams.
5
5
  # Copyright, 2017, by Kent Gruber.
6
6
  # Copyright, 2018, by Sokolov Yura.
7
7
 
8
- require_relative 'scheduler'
8
+ require_relative "scheduler"
9
9
 
10
10
  module Async
11
11
  # A wrapper around the the scheduler which binds it to the current thread automatically.