Skip to content

Commit 481191d

Browse files
committed
Rename Stop -> Cancel and related interfaces.
Retain backwards compatibility with appropriate aliases.
1 parent 4ea6072 commit 481191d

11 files changed

Lines changed: 227 additions & 172 deletions

File tree

lib/async/barrier.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,20 @@ def wait
8888
end
8989
end
9090

91-
# Stop all tasks held by the barrier.
91+
# Cancel all tasks held by the barrier.
9292
# @asynchronous May wait for tasks to finish executing.
93-
def stop
93+
def cancel
9494
@tasks.each do |waiting|
95-
waiting.task.stop
95+
waiting.task.cancel
9696
end
9797

9898
@finished.close
9999
end
100+
101+
# Backward compatibility alias for {#cancel}.
102+
# @deprecated Use {#cancel} instead.
103+
def stop
104+
cancel
105+
end
100106
end
101107
end

lib/async/cancel.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2025, by Samuel Williams.
5+
6+
module Async
7+
# Raised when a task is explicitly cancelled.
8+
class Cancel < Exception
9+
# Represents the source of the cancel operation.
10+
class Cause < Exception
11+
if RUBY_VERSION >= "3.4"
12+
# @returns [Array(Thread::Backtrace::Location)] The backtrace of the caller.
13+
def self.backtrace
14+
caller_locations(2..-1)
15+
end
16+
else
17+
# @returns [Array(String)] The backtrace of the caller.
18+
def self.backtrace
19+
caller(2..-1)
20+
end
21+
end
22+
23+
# Create a new cause of the cancel operation, with the given message.
24+
#
25+
# @parameter message [String] The error message.
26+
# @returns [Cause] The cause of the cancel operation.
27+
def self.for(message = "Task was cancelled!")
28+
instance = self.new(message)
29+
instance.set_backtrace(self.backtrace)
30+
return instance
31+
end
32+
end
33+
34+
if RUBY_VERSION < "3.5"
35+
# Create a new cancel operation.
36+
#
37+
# This is a compatibility method for Ruby versions before 3.5 where cause is not propagated correctly when using {Fiber#raise}
38+
#
39+
# @parameter message [String | Hash] The error message or a hash containing the cause.
40+
def initialize(message = "Task was cancelled")
41+
42+
if message.is_a?(Hash)
43+
@cause = message[:cause]
44+
message = "Task was cancelled"
45+
end
46+
47+
super(message)
48+
end
49+
50+
# @returns [Exception] The cause of the cancel operation.
51+
#
52+
# This is a compatibility method for Ruby versions before 3.5 where cause is not propagated correctly when using {Fiber#raise}, we explicitly capture the cause here.
53+
def cause
54+
super || @cause
55+
end
56+
end
57+
58+
# Used to defer cancelling the current task until later.
59+
class Later
60+
# Create a new cancel later operation.
61+
#
62+
# @parameter task [Task] The task to cancel later.
63+
# @parameter cause [Exception] The cause of the cancel operation.
64+
def initialize(task, cause = nil)
65+
@task = task
66+
@cause = cause
67+
end
68+
69+
# @returns [Boolean] Whether the task is alive.
70+
def alive?
71+
true
72+
end
73+
74+
# Transfer control to the operation - this will cancel the task.
75+
def transfer
76+
@task.cancel(false, cause: @cause)
77+
end
78+
end
79+
end
80+
end

lib/async/node.rb

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,18 +280,24 @@ def terminate
280280
return @children.nil?
281281
end
282282

283-
# Attempt to stop the current node immediately, including all non-transient children. Invokes {#stop_children} to stop all children.
283+
# Attempt to cancel the current node immediately, including all non-transient children. Invokes {#stop_children} to cancel all children.
284284
#
285-
# @parameter later [Boolean] Whether to defer stopping until some point in the future.
286-
def stop(later = false)
285+
# @parameter later [Boolean] Whether to defer cancelling until some point in the future.
286+
def cancel(later = false)
287287
# The implementation of this method may defer calling `stop_children`.
288288
stop_children(later)
289289
end
290290

291+
# Backward compatibility alias for {#cancel}.
292+
# @deprecated Use {#cancel} instead.
293+
def stop(...)
294+
cancel(...)
295+
end
296+
291297
# Attempt to stop all non-transient children.
292298
private def stop_children(later = false)
293299
@children&.each do |child|
294-
child.stop(later) unless child.transient?
300+
child.cancel(later) unless child.transient?
295301
end
296302
end
297303

@@ -301,11 +307,17 @@ def wait
301307
nil
302308
end
303309

304-
# Whether the node has been stopped.
305-
def stopped?
310+
# Whether the node has been cancelled.
311+
def cancelled?
306312
@children.nil?
307313
end
308314

315+
# Backward compatibility alias for {#cancelled?}.
316+
# @deprecated Use {#cancelled?} instead.
317+
def stopped?
318+
cancelled?
319+
end
320+
309321
# Print the hierarchy of the task tree from the given node.
310322
#
311323
# @parameter out [IO] The output stream to write to.

lib/async/scheduler.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def closed?
179179

180180
# @returns [String] A description of the scheduler.
181181
def to_s
182-
"\#<#{self.description} #{@children&.size || 0} children (#{stopped? ? 'stopped' : 'running'})>"
182+
"\#<#{self.description} #{@children&.size || 0} children (#{cancelled? ? 'cancelled' : 'running'})>"
183183
end
184184

185185
# Interrupt the event loop and cause it to exit.
@@ -511,15 +511,20 @@ def run_once(timeout = nil)
511511
return false
512512
end
513513

514-
# Stop all children, including transient children.
514+
# Cancel all children, including transient children.
515515
#
516516
# @public Since *Async v1*.
517-
def stop
517+
def cancel
518518
@children&.each do |child|
519-
child.stop
519+
child.cancel
520520
end
521521
end
522522

523+
# Backward compatibility alias for cancel.
524+
def stop
525+
cancel
526+
end
527+
523528
private def run_loop(&block)
524529
interrupt = nil
525530

lib/async/stop.rb

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,10 @@
11
# frozen_string_literal: true
22

33
# Released under the MIT License.
4-
# Copyright, 2025, by Samuel Williams.
4+
# Copyright, 2025-2026, by Samuel Williams.
55

6-
require "fiber"
7-
require "console"
6+
require_relative "cancel"
87

98
module Async
10-
# Raised when a task is explicitly stopped.
11-
class Stop < Exception
12-
# Represents the source of the stop operation.
13-
class Cause < Exception
14-
if RUBY_VERSION >= "3.4"
15-
# @returns [Array(Thread::Backtrace::Location)] The backtrace of the caller.
16-
def self.backtrace
17-
caller_locations(2..-1)
18-
end
19-
else
20-
# @returns [Array(String)] The backtrace of the caller.
21-
def self.backtrace
22-
caller(2..-1)
23-
end
24-
end
25-
26-
# Create a new cause of the stop operation, with the given message.
27-
#
28-
# @parameter message [String] The error message.
29-
# @returns [Cause] The cause of the stop operation.
30-
def self.for(message = "Task was stopped")
31-
instance = self.new(message)
32-
instance.set_backtrace(self.backtrace)
33-
return instance
34-
end
35-
end
36-
37-
if RUBY_VERSION < "3.5"
38-
# Create a new stop operation.
39-
#
40-
# This is a compatibility method for Ruby versions before 3.5 where cause is not propagated correctly when using {Fiber#raise}
41-
#
42-
# @parameter message [String | Hash] The error message or a hash containing the cause.
43-
def initialize(message = "Task was stopped")
44-
if message.is_a?(Hash)
45-
@cause = message[:cause]
46-
message = "Task was stopped"
47-
end
48-
49-
super(message)
50-
end
51-
52-
# @returns [Exception] The cause of the stop operation.
53-
#
54-
# This is a compatibility method for Ruby versions before 3.5 where cause is not propagated correctly when using {Fiber#raise}, we explicitly capture the cause here.
55-
def cause
56-
super || @cause
57-
end
58-
end
59-
60-
# Used to defer stopping the current task until later.
61-
class Later
62-
# Create a new stop later operation.
63-
#
64-
# @parameter task [Task] The task to stop later.
65-
# @parameter cause [Exception] The cause of the stop operation.
66-
def initialize(task, cause = nil)
67-
@task = task
68-
@cause = cause
69-
end
70-
71-
# @returns [Boolean] Whether the task is alive.
72-
def alive?
73-
true
74-
end
75-
76-
# Transfer control to the operation - this will stop the task.
77-
def transfer
78-
@task.stop(false, cause: @cause)
79-
end
80-
end
81-
end
9+
Stop = Cancel
8210
end

0 commit comments

Comments
 (0)