You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: lib/async/barrier.rb
+29-8
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,7 @@
5
5
6
6
require_relative"list"
7
7
require_relative"task"
8
+
require_relative"queue"
8
9
9
10
moduleAsync
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 @@ class Barrier
16
17
# @public Since *Async v1*.
17
18
definitialize(parent: nil)
18
19
@tasks=List.new
20
+
@finished=Queue.new
19
21
20
22
@parent=parent
21
23
end
@@ -41,11 +43,15 @@ def size
41
43
# Execute a child task and add it to the barrier.
42
44
# @asynchronous Executes the given block concurrently.
# Whether there are any tasks being held by the barrier.
@@ -55,14 +61,27 @@ def empty?
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
defwait
60
-
@tasks.eachdo |waiting|
69
+
while !@tasks.empty?
70
+
# Wait for a task to finish (we get the task node):
71
+
returnunlesswaiting=@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
+
ifblock_given?
81
+
yieldtask
82
+
else
83
+
# Wait for it to either complete or raise an error:
Copy file name to clipboardExpand all lines: releases.md
+1
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,7 @@
4
4
5
5
- Ruby v3.1 support is dropped.
6
6
-`Async::Wrapper` which was previously deprecated, is now removed.
7
+
-`Async::Barrier` now waits in order of completion rather than order of creation. This means that if you create a barrier with 3 tasks, and one of them completes (or fails) before the others, it will be the first to be yielded to the barrier.
Copy file name to clipboardExpand all lines: test/async/barrier.rb
+12-5
Original file line number
Diff line number
Diff line change
@@ -85,21 +85,28 @@
85
85
86
86
# It's possible for Barrier#wait to be interrupted with an unexpected exception, and this should not cause the barrier to incorrectly remove that task from the wait list.
0 commit comments