async 2.38.0 → 2.39.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/barrier.rb +31 -6
- data/lib/async/task.rb +3 -0
- data/lib/async/version.rb +1 -1
- data/license.md +1 -0
- data/readme.md +8 -8
- data/releases.md +8 -0
- data.tar.gz.sig +0 -0
- metadata +3 -2
- 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: 1d8427e86e8ab22c81e41dd6e7df7bd79087e3fa72ce786f07ae7b65d9d94545
|
|
4
|
+
data.tar.gz: 30e9e7e88b211aa21afe844e3f9510b5af39d2b4af1d97710ce533f581b5c57b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 337694b65547afc0d4c1568a02c0c08d03d0d70a8b2319b9b9a77660ad9f37c82ff3ab49a3856ebee477657df6b254d62e59ca6b31e9312484c02e696deab007
|
|
7
|
+
data.tar.gz: e9bc3a1a27f9ba9ea6004dee40df9b385d7959c30e7059521805e91d1f64e9ed16bbc0920b4eb3b1dae8a727ab52ed8258f95bb2605e219f311920bf3fe2b031
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/lib/async/barrier.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Released under the MIT License.
|
|
4
4
|
# Copyright, 2019-2026, by Samuel Williams.
|
|
5
|
+
# Copyright, 2026, by Tavian Barnes.
|
|
5
6
|
|
|
6
7
|
require_relative "list"
|
|
7
8
|
require_relative "task"
|
|
@@ -18,6 +19,7 @@ module Async
|
|
|
18
19
|
def initialize(parent: nil)
|
|
19
20
|
@tasks = List.new
|
|
20
21
|
@finished = Queue.new
|
|
22
|
+
@condition = Condition.new
|
|
21
23
|
|
|
22
24
|
@parent = parent
|
|
23
25
|
end
|
|
@@ -42,18 +44,32 @@ module Async
|
|
|
42
44
|
|
|
43
45
|
# Execute a child task and add it to the barrier.
|
|
44
46
|
# @asynchronous Executes the given block concurrently.
|
|
47
|
+
# @returns [Task] The task which was created to execute the block.
|
|
45
48
|
def async(*arguments, parent: (@parent or Task.current), **options, &block)
|
|
46
49
|
raise "Barrier is stopped!" if @finished.closed?
|
|
47
50
|
|
|
48
51
|
waiting = nil
|
|
49
52
|
|
|
50
|
-
parent.async(*arguments, **options) do |task, *arguments|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
task = parent.async(*arguments, **options) do |task, *arguments|
|
|
54
|
+
# Create a new list node for the task and add it to the list of waiting tasks:
|
|
55
|
+
node = TaskNode.new(task)
|
|
56
|
+
@tasks.append(node)
|
|
57
|
+
|
|
58
|
+
# Signal the outer async block that we have added the task to the list of waiting tasks, and that it can now wait for it to finish:
|
|
59
|
+
waiting = node
|
|
60
|
+
@condition.signal
|
|
61
|
+
|
|
62
|
+
# Invoke the block, which may raise an error. If it does, we will still signal that the task has finished:
|
|
53
63
|
block.call(task, *arguments)
|
|
54
64
|
ensure
|
|
55
|
-
|
|
65
|
+
# Signal that the task has finished, which will unblock the waiting task:
|
|
66
|
+
@finished.signal(node) unless @finished.closed?
|
|
56
67
|
end
|
|
68
|
+
|
|
69
|
+
# `parent.async` may yield before the child block executes, so we wait here until the child has appended itself to `@tasks`, ensuring `wait` cannot return early and miss tracking it:
|
|
70
|
+
@condition.wait while waiting.nil?
|
|
71
|
+
|
|
72
|
+
return task
|
|
57
73
|
end
|
|
58
74
|
|
|
59
75
|
# Whether there are any tasks being held by the barrier.
|
|
@@ -65,12 +81,17 @@ module Async
|
|
|
65
81
|
# 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.
|
|
66
82
|
#
|
|
67
83
|
# @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.
|
|
84
|
+
# @returns [Integer | Nil] The number of tasks which were waited for, or `nil` if there were no tasks to wait for.
|
|
68
85
|
#
|
|
69
86
|
# @asynchronous Will wait for tasks to finish executing.
|
|
70
87
|
def wait
|
|
71
|
-
|
|
88
|
+
return nil if @tasks.empty?
|
|
89
|
+
count = 0
|
|
90
|
+
|
|
91
|
+
while true
|
|
72
92
|
# Wait for a task to finish (we get the task node):
|
|
73
|
-
|
|
93
|
+
break unless waiting = @finished.wait
|
|
94
|
+
count += 1
|
|
74
95
|
|
|
75
96
|
# Remove the task as it is now finishing:
|
|
76
97
|
@tasks.remove?(waiting)
|
|
@@ -85,7 +106,11 @@ module Async
|
|
|
85
106
|
# Wait for it to either complete or raise an error:
|
|
86
107
|
task.wait
|
|
87
108
|
end
|
|
109
|
+
|
|
110
|
+
break if @tasks.empty?
|
|
88
111
|
end
|
|
112
|
+
|
|
113
|
+
return count
|
|
89
114
|
end
|
|
90
115
|
|
|
91
116
|
# Cancel all tasks held by the barrier.
|
data/lib/async/task.rb
CHANGED
|
@@ -456,6 +456,9 @@ module Async
|
|
|
456
456
|
|
|
457
457
|
# Finish the current task, moving any children to the parent.
|
|
458
458
|
def finish!
|
|
459
|
+
# Break the cycle:
|
|
460
|
+
@fiber&.async_task = nil
|
|
461
|
+
|
|
459
462
|
# Don't hold references to the fiber or block after the task has finished:
|
|
460
463
|
@fiber = nil
|
|
461
464
|
@block = nil # If some how we went directly from initialized to finished.
|
data/lib/async/version.rb
CHANGED
data/license.md
CHANGED
|
@@ -35,6 +35,7 @@ Copyright, 2025-2026, by Shopify Inc.
|
|
|
35
35
|
Copyright, 2025, by Josh Teeter.
|
|
36
36
|
Copyright, 2025, by Jatin Goyal.
|
|
37
37
|
Copyright, 2025, by Yuhi Sato.
|
|
38
|
+
Copyright, 2026, by Tavian Barnes.
|
|
38
39
|
|
|
39
40
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
40
41
|
of this software and associated documentation files (the "Software"), to deal
|
data/readme.md
CHANGED
|
@@ -35,6 +35,14 @@ 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.39.0
|
|
39
|
+
|
|
40
|
+
- `Async::Barrier#wait` now returns the number of tasks that were waited for, or `nil` if there were no tasks to wait for. This provides better feedback about the operation, and allows you to know how many tasks were involved in the wait.
|
|
41
|
+
|
|
42
|
+
### v2.38.1
|
|
43
|
+
|
|
44
|
+
- Fix `Barrier#async` when `parent.async` yields before the child block executes. Previously, `Barrier#wait` could return early and miss tracking the task entirely, because the task had not yet appended itself to the barrier's task list.
|
|
45
|
+
|
|
38
46
|
### v2.38.0
|
|
39
47
|
|
|
40
48
|
- Rename `Task#stop` to `Task#cancel` for better clarity and consistency with common concurrency terminology. The old `stop` method is still available as an alias for backward compatibility, but it is recommended to use `cancel` going forward.
|
|
@@ -71,14 +79,6 @@ Please see the [project releases](https://socketry.github.io/async/releases/inde
|
|
|
71
79
|
|
|
72
80
|
- [`Kernel::Barrier` Convenience Interface](https://socketry.github.io/async/releases/index#kernel::barrier-convenience-interface)
|
|
73
81
|
|
|
74
|
-
### v2.33.0
|
|
75
|
-
|
|
76
|
-
- Introduce `Async::Promise.fulfill` for optional promise resolution.
|
|
77
|
-
|
|
78
|
-
### v2.32.1
|
|
79
|
-
|
|
80
|
-
- Fix typo in documentation.
|
|
81
|
-
|
|
82
82
|
## See Also
|
|
83
83
|
|
|
84
84
|
- [async-http](https://github.com/socketry/async-http) — Asynchronous HTTP client/server.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v2.39.0
|
|
4
|
+
|
|
5
|
+
- `Async::Barrier#wait` now returns the number of tasks that were waited for, or `nil` if there were no tasks to wait for. This provides better feedback about the operation, and allows you to know how many tasks were involved in the wait.
|
|
6
|
+
|
|
7
|
+
## v2.38.1
|
|
8
|
+
|
|
9
|
+
- Fix `Barrier#async` when `parent.async` yields before the child block executes. Previously, `Barrier#wait` could return early and miss tracking the task entirely, because the task had not yet appended itself to the barrier's task list.
|
|
10
|
+
|
|
3
11
|
## v2.38.0
|
|
4
12
|
|
|
5
13
|
- Rename `Task#stop` to `Task#cancel` for better clarity and consistency with common concurrency terminology. The old `stop` method is still available as an alias for backward compatibility, but it is recommended to use `cancel` going forward.
|
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.39.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -37,6 +37,7 @@ authors:
|
|
|
37
37
|
- Shigeru Nakajima
|
|
38
38
|
- Sokolov Yura
|
|
39
39
|
- Stefan Wrobel
|
|
40
|
+
- Tavian Barnes
|
|
40
41
|
- Trevor Turk
|
|
41
42
|
- Yuhi Sato
|
|
42
43
|
bindir: bin
|
|
@@ -215,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
215
216
|
- !ruby/object:Gem::Version
|
|
216
217
|
version: '0'
|
|
217
218
|
requirements: []
|
|
218
|
-
rubygems_version:
|
|
219
|
+
rubygems_version: 3.6.9
|
|
219
220
|
specification_version: 4
|
|
220
221
|
summary: A concurrency framework for Ruby.
|
|
221
222
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|