Skip to content

Commit bd38e33

Browse files
committed
Move cancellation out
1 parent 38ab132 commit bd38e33

File tree

3 files changed

+82
-79
lines changed

3 files changed

+82
-79
lines changed

lib/concurrent-edge.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
require 'concurrent/edge/lock_free_linked_set'
1111

1212
require 'concurrent/edge/promises'
13+
require 'concurrent/edge/cancellation'

lib/concurrent/edge/cancellation.rb

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
module Concurrent
2+
3+
# TODO example: parallel jobs, cancel them all when one fails, clean-up in zip
4+
# inspired by https://msdn.microsoft.com/en-us/library/dd537607(v=vs.110).aspx
5+
class Cancellation < Synchronization::Object
6+
safe_initialization!
7+
8+
def self.create(future_or_event = Promises.resolvable_event, *resolve_args)
9+
cancellation = new(future_or_event, *resolve_args)
10+
[cancellation, cancellation.token]
11+
end
12+
13+
private_class_method :new
14+
15+
def initialize(future, *resolve_args)
16+
raise ArgumentError, 'future is not Resolvable' unless future.is_a?(Promises::Resolvable)
17+
@Cancel = future
18+
@Token = Token.new @Cancel.with_hidden_resolvable
19+
@ResolveArgs = resolve_args
20+
end
21+
22+
def token
23+
@Token
24+
end
25+
26+
def cancel(raise_on_repeated_call = true)
27+
!!@Cancel.resolve(*@ResolveArgs, raise_on_repeated_call)
28+
end
29+
30+
def canceled?
31+
@Cancel.resolved?
32+
end
33+
34+
class Token < Synchronization::Object
35+
safe_initialization!
36+
37+
def initialize(cancel)
38+
@Cancel = cancel
39+
end
40+
41+
def to_event
42+
@Cancel.to_event
43+
end
44+
45+
def to_future
46+
@Cancel.to_future
47+
end
48+
49+
def on_cancellation(*args, &block)
50+
@Cancel.on_resolution *args, &block
51+
end
52+
53+
def canceled?
54+
@Cancel.resolved?
55+
end
56+
57+
def loop_until_canceled(&block)
58+
until canceled?
59+
result = block.call
60+
end
61+
result
62+
end
63+
64+
def raise_if_canceled(error = CancelledOperationError)
65+
raise error if canceled?
66+
self
67+
end
68+
69+
def join(*tokens, &block)
70+
block ||= -> tokens { Promises.any_event(*tokens.map(&:to_event)) }
71+
self.class.new block.call([@Cancel, *tokens])
72+
end
73+
74+
end
75+
76+
private_constant :Token
77+
78+
# FIXME (pitr-ch 27-Mar-2016): cooperation with mutex, condition, select etc?
79+
# TODO (pitr-ch 27-Mar-2016): examples (scheduled to be cancelled in 10 sec)
80+
end
81+
end

lib/concurrent/edge/promises.rb

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,85 +1959,6 @@ def each_body(value, &block)
19591959
end
19601960
end
19611961

1962-
# TODO example: parallel jobs, cancell them all when one fails, clean-up in zip
1963-
# inspired by https://msdn.microsoft.com/en-us/library/dd537607(v=vs.110).aspx
1964-
class Cancellation < Synchronization::Object
1965-
safe_initialization!
1966-
1967-
def self.create(future_or_event = Promises.resolvable_event, *resolve_args)
1968-
cancellation = new(future_or_event, *resolve_args)
1969-
[cancellation, cancellation.token]
1970-
end
1971-
1972-
private_class_method :new
1973-
1974-
def initialize(future, *resolve_args)
1975-
raise ArgumentError, 'future is not Resolvable' unless future.is_a?(Promises::Resolvable)
1976-
@Cancel = future
1977-
@Token = Token.new @Cancel.with_hidden_resolvable
1978-
@ResolveArgs = resolve_args
1979-
end
1980-
1981-
def token
1982-
@Token
1983-
end
1984-
1985-
def cancel(raise_on_repeated_call = true)
1986-
!!@Cancel.resolve(*@ResolveArgs, raise_on_repeated_call)
1987-
end
1988-
1989-
def canceled?
1990-
@Cancel.resolved?
1991-
end
1992-
1993-
class Token < Synchronization::Object
1994-
safe_initialization!
1995-
1996-
def initialize(cancel)
1997-
@Cancel = cancel
1998-
end
1999-
2000-
def to_event
2001-
@Cancel.to_event
2002-
end
2003-
2004-
def to_future
2005-
@Cancel.to_future
2006-
end
2007-
2008-
def on_cancellation(*args, &block)
2009-
@Cancel.on_resolution *args, &block
2010-
end
2011-
2012-
def canceled?
2013-
@Cancel.resolved?
2014-
end
2015-
2016-
def loop_until_canceled(&block)
2017-
until canceled?
2018-
result = block.call
2019-
end
2020-
result
2021-
end
2022-
2023-
def raise_if_canceled(error = CancelledOperationError)
2024-
raise error if canceled?
2025-
self
2026-
end
2027-
2028-
def join(*tokens, &block)
2029-
block ||= -> tokens { Promises.any_event(*tokens.map(&:to_event)) }
2030-
self.class.new block.call([@Cancel, *tokens])
2031-
end
2032-
2033-
end
2034-
2035-
private_constant :Token
2036-
2037-
# TODO (pitr-ch 27-Mar-2016): cooperation with mutex, select etc?
2038-
# TODO (pitr-ch 27-Mar-2016): examples (scheduled to be cancelled in 10 sec)
2039-
end
2040-
20411962
class Promises::Throttle < Synchronization::Object
20421963

20431964
safe_initialization!

0 commit comments

Comments
 (0)