5
5
require 'concurrent/executor/executor'
6
6
require 'concurrent/executor/timer_set'
7
7
require 'concurrent/utility/monotonic_time'
8
+ require 'concurrent/concern/deprecation'
8
9
9
10
module Concurrent
11
+ include Concern ::Deprecation
10
12
11
13
# `ScheduledTask` is a close relative of `Concurrent::Future` but with one
12
14
# important difference: A `Future` is set to execute as soon as possible
13
15
# whereas a `ScheduledTask` is set to execute after a specified delay. This
14
16
# implementation is loosely based on Java's
15
- # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html).
17
+ # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html).
16
18
# It is a more feature-rich variant of {Concurrent.timer}.
17
- #
19
+ #
18
20
# The *intended* schedule time of task execution is set on object construction
19
21
# with the `delay` argument. The delay is a numeric (floating point or integer)
20
22
# representing a number of seconds in the future. Any other value or a numeric
21
23
# equal to or less than zero will result in an exception. The *actual* schedule
22
24
# time of task execution is set when the `execute` method is called.
23
- #
25
+ #
24
26
# The constructor can also be given zero or more processing options. Currently
25
27
# the only supported options are those recognized by the
26
- # [Dereferenceable](Dereferenceable) module.
27
- #
28
+ # [Dereferenceable](Dereferenceable) module.
29
+ #
28
30
# The final constructor argument is a block representing the task to be performed.
29
31
# If no block is given an `ArgumentError` will be raised.
30
- #
32
+ #
31
33
# **States**
32
- #
34
+ #
33
35
# `ScheduledTask` mixes in the [Obligation](Obligation) module thus giving it
34
36
# "future" behavior. This includes the expected lifecycle states. `ScheduledTask`
35
37
# has one additional state, however. While the task (block) is being executed the
36
38
# state of the object will be `:processing`. This additional state is necessary
37
- # because it has implications for task cancellation.
38
- #
39
+ # because it has implications for task cancellation.
40
+ #
39
41
# **Cancellation**
40
- #
42
+ #
41
43
# A `:pending` task can be cancelled using the `#cancel` method. A task in any
42
44
# other state, including `:processing`, cannot be cancelled. The `#cancel`
43
45
# method returns a boolean indicating the success of the cancellation attempt.
44
- # A cancelled `ScheduledTask` cannot be restarted. It is immutable.
45
- #
46
+ # A cancelled `ScheduledTask` cannot be restarted. It is immutable.
47
+ #
46
48
# **Obligation and Observation**
47
- #
49
+ #
48
50
# The result of a `ScheduledTask` can be obtained either synchronously or
49
51
# asynchronously. `ScheduledTask` mixes in both the [Obligation](Obligation)
50
52
# module and the
51
53
# [Observable](http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html)
52
54
# module from the Ruby standard library. With one exception `ScheduledTask`
53
- # behaves identically to [Future](Observable) with regard to these modules.
55
+ # behaves identically to [Future](Observable) with regard to these modules.
54
56
#
55
57
# @!macro copy_options
56
58
#
@@ -59,83 +61,83 @@ module Concurrent
59
61
# require 'concurrent'
60
62
# require 'thread' # for Queue
61
63
# require 'open-uri' # for open(uri)
62
- #
64
+ #
63
65
# class Ticker
64
66
# def get_year_end_closing(symbol, year)
65
67
# uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
66
68
# data = open(uri) {|f| f.collect{|line| line.strip } }
67
69
# data[1].split(',')[4].to_f
68
70
# end
69
71
# end
70
- #
72
+ #
71
73
# # Future
72
74
# price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
73
75
# price.state #=> :pending
74
76
# sleep(1) # do other stuff
75
77
# price.value #=> 63.65
76
78
# price.state #=> :fulfilled
77
- #
79
+ #
78
80
# # ScheduledTask
79
81
# task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
80
82
# task.state #=> :pending
81
83
# sleep(3) # do other stuff
82
84
# task.value #=> 25.96
83
- #
85
+ #
84
86
# @example Successful task execution
85
- #
87
+ #
86
88
# task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }
87
89
# task.state #=> :unscheduled
88
90
# task.execute
89
91
# task.state #=> pending
90
- #
92
+ #
91
93
# # wait for it...
92
94
# sleep(3)
93
- #
95
+ #
94
96
# task.unscheduled? #=> false
95
97
# task.pending? #=> false
96
98
# task.fulfilled? #=> true
97
99
# task.rejected? #=> false
98
100
# task.value #=> 'What does the fox say?'
99
- #
101
+ #
100
102
# @example One line creation and execution
101
- #
103
+ #
102
104
# task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }.execute
103
105
# task.state #=> pending
104
- #
106
+ #
105
107
# task = Concurrent::ScheduledTask.execute(2){ 'What do you get when you multiply 6 by 9?' }
106
108
# task.state #=> pending
107
- #
109
+ #
108
110
# @example Failed task execution
109
- #
111
+ #
110
112
# task = Concurrent::ScheduledTask.execute(2){ raise StandardError.new('Call me maybe?') }
111
113
# task.pending? #=> true
112
- #
114
+ #
113
115
# # wait for it...
114
116
# sleep(3)
115
- #
117
+ #
116
118
# task.unscheduled? #=> false
117
119
# task.pending? #=> false
118
120
# task.fulfilled? #=> false
119
121
# task.rejected? #=> true
120
122
# task.value #=> nil
121
- # task.reason #=> #<StandardError: Call me maybe?>
122
- #
123
+ # task.reason #=> #<StandardError: Call me maybe?>
124
+ #
123
125
# @example Task execution with observation
124
- #
126
+ #
125
127
# observer = Class.new{
126
128
# def update(time, value, reason)
127
129
# puts "The task completed at #{time} with value '#{value}'"
128
130
# end
129
131
# }.new
130
- #
132
+ #
131
133
# task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }
132
134
# task.add_observer(observer)
133
135
# task.execute
134
136
# task.pending? #=> true
135
- #
137
+ #
136
138
# # wait for it...
137
139
# sleep(3)
138
- #
140
+ #
139
141
# #>> The task completed at 2013-11-07 12:26:09 -0500 with value 'What does the fox say?'
140
142
#
141
143
# @!macro monotonic_clock_warning
@@ -196,12 +198,12 @@ def initial_delay
196
198
#
197
199
# @deprecated use {#initial_delay} instead
198
200
def delay
199
- warn '[DEPRECATED] use # initial_delay instead '
201
+ deprecated_method 'delay' , ' initial_delay'
200
202
initial_delay
201
203
end
202
204
203
205
# The monotonic time at which the the task is scheduled to be executed.
204
- #
206
+ #
205
207
# @return [Float] the schedule time or nil if `unscheduled`
206
208
def schedule_time
207
209
synchronize { @time }
@@ -234,7 +236,7 @@ def processing?
234
236
#
235
237
# @deprecated Use {#processing?} instead.
236
238
def in_progress?
237
- warn '[DEPRECATED] use # processing? instead '
239
+ deprecated_method 'in_progress?' , ' processing?'
238
240
processing?
239
241
end
240
242
@@ -260,7 +262,7 @@ def cancel
260
262
#
261
263
# @deprecated Use {#cancel} instead.
262
264
def stop
263
- warn '[DEPRECATED] use # cancel instead '
265
+ deprecated_method 'stop' , ' cancel'
264
266
cancel
265
267
end
266
268
@@ -363,7 +365,7 @@ def ns_reschedule(delay)
363
365
# @!visibility private
364
366
def calculate_delay! ( delay )
365
367
if delay . is_a? ( Time )
366
- warn '[DEPRECATED] Use an interval not a clock time; schedule is now based on a monotonic clock'
368
+ deprecated ' Use an interval not a clock time; schedule is now based on a monotonic clock'
367
369
now = Time . now
368
370
raise ArgumentError . new ( 'schedule time must be in the future' ) if delay <= now
369
371
delay . to_f - now . to_f
0 commit comments