async 2.33.0 → 2.34.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/idler.rb +26 -14
- data/lib/async/version.rb +1 -1
- data/lib/async.rb +1 -0
- data/lib/kernel/barrier.rb +31 -0
- data/readme.md +4 -4
- data/releases.md +23 -0
- data.tar.gz.sig +0 -0
- metadata +2 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05c05a5ba6d2dc436a12de9ff3cb562b3376892fd8c6615be8c4eb654d570fef
|
4
|
+
data.tar.gz: 2cb04cbecc3237b4476e5f42e4e130e8116ea10890c1b766140b238451c13f81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16d4488b9d5fa9702bba6fead00c9c772402f792817daba79596cdf573e9f7b111ab77b85166d9b7b93c92babd9a717bf8fe11aa56ae67beded351fda99eaa7b
|
7
|
+
data.tar.gz: 289f3a854fcda83b35e92a1ebc14425722fdc856f8dfaa60e29f630ba79b3d72269816f7f01f940aa8926685701cd5ef1ba285a0576f91354107083cfaf96905
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/async/idler.rb
CHANGED
@@ -13,10 +13,13 @@ module Async
|
|
13
13
|
# @parameter maximum_load [Numeric] The maximum load before we start shedding work.
|
14
14
|
# @parameter backoff [Numeric] The initial backoff time, used for delaying work.
|
15
15
|
# @parameter parent [Interface(:async) | Nil] The parent task to use for async operations.
|
16
|
-
def initialize(maximum_load = 0.8, backoff: 0.
|
16
|
+
def initialize(maximum_load = 0.8, backoff: 0.001, parent: nil)
|
17
17
|
@maximum_load = maximum_load
|
18
18
|
@backoff = backoff
|
19
|
+
@current = backoff
|
20
|
+
|
19
21
|
@parent = parent
|
22
|
+
@mutex = Mutex.new
|
20
23
|
end
|
21
24
|
|
22
25
|
# Wait until the system is idle, then execute the given block in a new task.
|
@@ -38,20 +41,29 @@ module Async
|
|
38
41
|
#
|
39
42
|
# If the scheduler is overloaded, this method will sleep for an exponentially increasing amount of time.
|
40
43
|
def wait
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
while true
|
45
|
-
load = scheduler.load
|
46
|
-
|
47
|
-
break if load < @maximum_load
|
44
|
+
@mutex.synchronize do
|
45
|
+
scheduler = Fiber.scheduler
|
48
46
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
while true
|
48
|
+
load = scheduler.load
|
49
|
+
|
50
|
+
if load <= @maximum_load
|
51
|
+
# Even though load is okay, if @current is high, we were recently overloaded. Sleep proportionally to prevent burst after load drop:
|
52
|
+
if @current > @backoff
|
53
|
+
# Sleep a fraction of @current to rate limit:
|
54
|
+
sleep(@current - @backoff)
|
55
|
+
|
56
|
+
# Decay @current gently towards @backoff:
|
57
|
+
alpha = 0.99
|
58
|
+
@current *= alpha + (1.0 - alpha) * (load / @maximum_load)
|
59
|
+
end
|
60
|
+
|
61
|
+
break
|
62
|
+
else
|
63
|
+
# We're overloaded, so increase backoff:
|
64
|
+
@current *= (load / @maximum_load)
|
65
|
+
sleep(@current)
|
66
|
+
end
|
55
67
|
end
|
56
68
|
end
|
57
69
|
end
|
data/lib/async/version.rb
CHANGED
data/lib/async.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative "sync"
|
7
|
+
require_relative "../async/barrier"
|
8
|
+
require_relative "../async/idler"
|
9
|
+
|
10
|
+
module Kernel
|
11
|
+
# Create a barrier, yield it to the block, and then wait for all tasks to complete.
|
12
|
+
#
|
13
|
+
# If no scheduler is running, one will be created automatically for the duration of the block.
|
14
|
+
#
|
15
|
+
# By default, the barrier uses an `Async::Idler` to manage load, but this can be overridden by providing a different parent or `nil` to disable load management.
|
16
|
+
#
|
17
|
+
# @parameter parent [Task | Semaphore | Nil] The parent for holding any children tasks.
|
18
|
+
# @parameter **options [Hash] Additional options passed to {Kernel::Sync}.
|
19
|
+
# @public Since *Async v2.34*.
|
20
|
+
def Barrier(parent: Async::Idler.new, **options)
|
21
|
+
Sync(**options) do |task|
|
22
|
+
barrier = ::Async::Barrier.new(parent: parent)
|
23
|
+
|
24
|
+
yield barrier
|
25
|
+
|
26
|
+
barrier.wait
|
27
|
+
ensure
|
28
|
+
barrier&.stop
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/readme.md
CHANGED
@@ -35,6 +35,10 @@ 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.34.0
|
39
|
+
|
40
|
+
- [`Kernel::Barrier` Convenience Interface](https://socketry.github.io/async/releases/index#kernel::barrier-convenience-interface)
|
41
|
+
|
38
42
|
### v2.33.0
|
39
43
|
|
40
44
|
- Introduce `Async::Promise.fulfill` for optional promise resolution.
|
@@ -80,10 +84,6 @@ This release introduces thread-safety as a core concept of Async. Many core clas
|
|
80
84
|
|
81
85
|
- Suppress excessive warning in `Async::Scheduler#async`.
|
82
86
|
|
83
|
-
### v2.27.3
|
84
|
-
|
85
|
-
- Ensure trace attributes are strings, fixes integration with OpenTelemetry.
|
86
|
-
|
87
87
|
## See Also
|
88
88
|
|
89
89
|
- [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client/server.
|
data/releases.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v2.34.0
|
4
|
+
|
5
|
+
### `Kernel::Barrier` Convenience Interface
|
6
|
+
|
7
|
+
Starting multiple concurrent tasks and waiting for them to finish is a common pattern. This change introduces a small ergonomic helper, `Barrier`, defined in `Kernel`, that encapsulates this behavior: it creates an `Async::Barrier`, yields it to a block, waits for completion (using `Sync` to run a reactor if needed), and ensures remaining tasks are stopped on exit.
|
8
|
+
|
9
|
+
``` ruby
|
10
|
+
require 'async'
|
11
|
+
|
12
|
+
Barrier do |barrier|
|
13
|
+
3.times do |i|
|
14
|
+
barrier.async do |task|
|
15
|
+
sleep(rand * 0.1) # Simulate work
|
16
|
+
puts "Task #{i} completed"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# All tasks are guaranteed to complete or be stopped when the block exits.
|
22
|
+
```
|
23
|
+
|
24
|
+
If an exception is raised by a task, it will be propagated to the caller, and any remaining tasks will be stopped. The `parent:` parameter can be used to specify a parent task for the barrier, otherwise it will use the current task if available, or create a new reactor if not.
|
25
|
+
|
3
26
|
## v2.33.0
|
4
27
|
|
5
28
|
- Introduce `Async::Promise.fulfill` for optional promise resolution.
|
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.
|
4
|
+
version: 2.34.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -180,6 +180,7 @@ files:
|
|
180
180
|
- lib/async/version.rb
|
181
181
|
- lib/async/waiter.rb
|
182
182
|
- lib/kernel/async.rb
|
183
|
+
- lib/kernel/barrier.rb
|
183
184
|
- lib/kernel/sync.rb
|
184
185
|
- lib/metrics/provider/async.rb
|
185
186
|
- lib/metrics/provider/async/task.rb
|
metadata.gz.sig
CHANGED
Binary file
|