concurrent-ruby 0.9.0.pre3-java → 0.9.1-java

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.
@@ -1,5 +1,4 @@
1
1
  require 'thread'
2
- require 'concurrent/configuration'
3
2
  require 'concurrent/concern/obligation'
4
3
  require 'concurrent/executor/executor'
5
4
  require 'concurrent/executor/immediate_executor'
@@ -15,6 +15,10 @@ module Concurrent
15
15
  # Raised when an attempt is made to violate an immutability guarantee.
16
16
  ImmutabilityError = Class.new(Error)
17
17
 
18
+ # Raised when an operation is attempted which is not legal given the
19
+ # receiver's current state
20
+ IllegalOperationError = Class.new(Error)
21
+
18
22
  # Raised when an object's methods are called when it has not been
19
23
  # properly initialized.
20
24
  InitializationError = Class.new(Error)
@@ -1,5 +1,6 @@
1
- require 'concurrent/executor/executor_service'
1
+ require 'concurrent/configuration'
2
2
  require 'concurrent/concern/deprecation'
3
+ require 'concurrent/executor/executor_service'
3
4
 
4
5
  module Concurrent
5
6
 
@@ -166,7 +166,7 @@ module Concurrent
166
166
  def ns_kill_execution
167
167
  # TODO log out unprocessed tasks in queue
168
168
  # TODO try to shutdown first?
169
- @pool.each &:kill
169
+ @pool.each(&:kill)
170
170
  @pool.clear
171
171
  @ready.clear
172
172
  end
@@ -297,32 +297,31 @@ module Concurrent
297
297
  private
298
298
 
299
299
  def create_worker(queue, pool, idletime)
300
- Thread.new(queue, pool, idletime) do |queue, pool, idletime|
300
+ Thread.new(queue, pool, idletime) do |my_queue, my_pool, my_idletime|
301
301
  last_message = Concurrent.monotonic_time
302
302
  catch(:stop) do
303
303
  loop do
304
304
 
305
- case message = queue.pop
305
+ case message = my_queue.pop
306
306
  when :idle_test
307
- if (Concurrent.monotonic_time - last_message) > idletime
308
- pool.remove_busy_worker(self)
307
+ if (Concurrent.monotonic_time - last_message) > my_idletime
308
+ my_pool.remove_busy_worker(self)
309
309
  throw :stop
310
310
  else
311
- pool.worker_not_old_enough(self)
311
+ my_pool.worker_not_old_enough(self)
312
312
  end
313
313
 
314
314
  when :stop
315
- pool.remove_busy_worker(self)
315
+ my_pool.remove_busy_worker(self)
316
316
  throw :stop
317
317
 
318
318
  else
319
319
  task, args = message
320
- run_task pool, task, args
320
+ run_task my_pool, task, args
321
321
  last_message = Concurrent.monotonic_time
322
322
 
323
- pool.ready_worker(self)
323
+ my_pool.ready_worker(self)
324
324
  end
325
-
326
325
  end
327
326
  end
328
327
  end
@@ -1,56 +1,56 @@
1
1
  require 'concurrent/errors'
2
2
  require 'concurrent/ivar'
3
- require 'concurrent/configuration'
4
3
  require 'concurrent/collection/copy_on_notify_observer_set'
5
4
  require 'concurrent/executor/executor'
6
- require 'concurrent/executor/timer_set'
7
5
  require 'concurrent/utility/monotonic_time'
6
+ require 'concurrent/concern/deprecation'
8
7
 
9
8
  module Concurrent
9
+ include Concern::Deprecation
10
10
 
11
11
  # `ScheduledTask` is a close relative of `Concurrent::Future` but with one
12
12
  # important difference: A `Future` is set to execute as soon as possible
13
13
  # whereas a `ScheduledTask` is set to execute after a specified delay. This
14
14
  # implementation is loosely based on Java's
15
- # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html).
15
+ # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html).
16
16
  # It is a more feature-rich variant of {Concurrent.timer}.
17
- #
17
+ #
18
18
  # The *intended* schedule time of task execution is set on object construction
19
19
  # with the `delay` argument. The delay is a numeric (floating point or integer)
20
20
  # representing a number of seconds in the future. Any other value or a numeric
21
21
  # equal to or less than zero will result in an exception. The *actual* schedule
22
22
  # time of task execution is set when the `execute` method is called.
23
- #
23
+ #
24
24
  # The constructor can also be given zero or more processing options. Currently
25
25
  # the only supported options are those recognized by the
26
- # [Dereferenceable](Dereferenceable) module.
27
- #
26
+ # [Dereferenceable](Dereferenceable) module.
27
+ #
28
28
  # The final constructor argument is a block representing the task to be performed.
29
29
  # If no block is given an `ArgumentError` will be raised.
30
- #
30
+ #
31
31
  # **States**
32
- #
32
+ #
33
33
  # `ScheduledTask` mixes in the [Obligation](Obligation) module thus giving it
34
34
  # "future" behavior. This includes the expected lifecycle states. `ScheduledTask`
35
35
  # has one additional state, however. While the task (block) is being executed the
36
36
  # state of the object will be `:processing`. This additional state is necessary
37
- # because it has implications for task cancellation.
38
- #
37
+ # because it has implications for task cancellation.
38
+ #
39
39
  # **Cancellation**
40
- #
40
+ #
41
41
  # A `:pending` task can be cancelled using the `#cancel` method. A task in any
42
42
  # other state, including `:processing`, cannot be cancelled. The `#cancel`
43
43
  # method returns a boolean indicating the success of the cancellation attempt.
44
- # A cancelled `ScheduledTask` cannot be restarted. It is immutable.
45
- #
44
+ # A cancelled `ScheduledTask` cannot be restarted. It is immutable.
45
+ #
46
46
  # **Obligation and Observation**
47
- #
47
+ #
48
48
  # The result of a `ScheduledTask` can be obtained either synchronously or
49
49
  # asynchronously. `ScheduledTask` mixes in both the [Obligation](Obligation)
50
50
  # module and the
51
51
  # [Observable](http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html)
52
52
  # module from the Ruby standard library. With one exception `ScheduledTask`
53
- # behaves identically to [Future](Observable) with regard to these modules.
53
+ # behaves identically to [Future](Observable) with regard to these modules.
54
54
  #
55
55
  # @!macro copy_options
56
56
  #
@@ -59,7 +59,7 @@ module Concurrent
59
59
  # require 'concurrent'
60
60
  # require 'thread' # for Queue
61
61
  # require 'open-uri' # for open(uri)
62
- #
62
+ #
63
63
  # class Ticker
64
64
  # def get_year_end_closing(symbol, year)
65
65
  # uri = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&a=11&b=01&c=#{year}&d=11&e=31&f=#{year}&g=m"
@@ -67,75 +67,75 @@ module Concurrent
67
67
  # data[1].split(',')[4].to_f
68
68
  # end
69
69
  # end
70
- #
70
+ #
71
71
  # # Future
72
72
  # price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013) }
73
73
  # price.state #=> :pending
74
74
  # sleep(1) # do other stuff
75
75
  # price.value #=> 63.65
76
76
  # price.state #=> :fulfilled
77
- #
77
+ #
78
78
  # # ScheduledTask
79
79
  # task = Concurrent::ScheduledTask.execute(2){ Ticker.new.get_year_end_closing('INTC', 2013) }
80
80
  # task.state #=> :pending
81
81
  # sleep(3) # do other stuff
82
82
  # task.value #=> 25.96
83
- #
83
+ #
84
84
  # @example Successful task execution
85
- #
85
+ #
86
86
  # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }
87
87
  # task.state #=> :unscheduled
88
88
  # task.execute
89
89
  # task.state #=> pending
90
- #
90
+ #
91
91
  # # wait for it...
92
92
  # sleep(3)
93
- #
93
+ #
94
94
  # task.unscheduled? #=> false
95
95
  # task.pending? #=> false
96
96
  # task.fulfilled? #=> true
97
97
  # task.rejected? #=> false
98
98
  # task.value #=> 'What does the fox say?'
99
- #
99
+ #
100
100
  # @example One line creation and execution
101
- #
101
+ #
102
102
  # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }.execute
103
103
  # task.state #=> pending
104
- #
104
+ #
105
105
  # task = Concurrent::ScheduledTask.execute(2){ 'What do you get when you multiply 6 by 9?' }
106
106
  # task.state #=> pending
107
- #
107
+ #
108
108
  # @example Failed task execution
109
- #
109
+ #
110
110
  # task = Concurrent::ScheduledTask.execute(2){ raise StandardError.new('Call me maybe?') }
111
111
  # task.pending? #=> true
112
- #
112
+ #
113
113
  # # wait for it...
114
114
  # sleep(3)
115
- #
115
+ #
116
116
  # task.unscheduled? #=> false
117
117
  # task.pending? #=> false
118
118
  # task.fulfilled? #=> false
119
119
  # task.rejected? #=> true
120
120
  # task.value #=> nil
121
- # task.reason #=> #<StandardError: Call me maybe?>
122
- #
121
+ # task.reason #=> #<StandardError: Call me maybe?>
122
+ #
123
123
  # @example Task execution with observation
124
- #
124
+ #
125
125
  # observer = Class.new{
126
126
  # def update(time, value, reason)
127
127
  # puts "The task completed at #{time} with value '#{value}'"
128
128
  # end
129
129
  # }.new
130
- #
130
+ #
131
131
  # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }
132
132
  # task.add_observer(observer)
133
133
  # task.execute
134
134
  # task.pending? #=> true
135
- #
135
+ #
136
136
  # # wait for it...
137
137
  # sleep(3)
138
- #
138
+ #
139
139
  # #>> The task completed at 2013-11-07 12:26:09 -0500 with value 'What does the fox say?'
140
140
  #
141
141
  # @!macro monotonic_clock_warning
@@ -196,12 +196,12 @@ module Concurrent
196
196
  #
197
197
  # @deprecated use {#initial_delay} instead
198
198
  def delay
199
- warn '[DEPRECATED] use #initial_delay instead'
199
+ deprecated_method 'delay', 'initial_delay'
200
200
  initial_delay
201
201
  end
202
202
 
203
203
  # The monotonic time at which the the task is scheduled to be executed.
204
- #
204
+ #
205
205
  # @return [Float] the schedule time or nil if `unscheduled`
206
206
  def schedule_time
207
207
  synchronize { @time }
@@ -234,7 +234,7 @@ module Concurrent
234
234
  #
235
235
  # @deprecated Use {#processing?} instead.
236
236
  def in_progress?
237
- warn '[DEPRECATED] use #processing? instead'
237
+ deprecated_method 'in_progress?', 'processing?'
238
238
  processing?
239
239
  end
240
240
 
@@ -260,7 +260,7 @@ module Concurrent
260
260
  #
261
261
  # @deprecated Use {#cancel} instead.
262
262
  def stop
263
- warn '[DEPRECATED] use #cancel instead'
263
+ deprecated_method 'stop', 'cancel'
264
264
  cancel
265
265
  end
266
266
 
@@ -363,7 +363,7 @@ module Concurrent
363
363
  # @!visibility private
364
364
  def calculate_delay!(delay)
365
365
  if delay.is_a?(Time)
366
- warn '[DEPRECATED] Use an interval not a clock time; schedule is now based on a monotonic clock'
366
+ deprecated 'Use an interval not a clock time; schedule is now based on a monotonic clock'
367
367
  now = Time.now
368
368
  raise ArgumentError.new('schedule time must be in the future') if delay <= now
369
369
  delay.to_f - now.to_f
@@ -4,7 +4,6 @@ module Concurrent
4
4
  module Synchronization
5
5
 
6
6
  if Concurrent.on_jruby?
7
- require 'jruby'
8
7
 
9
8
  # @!visibility private
10
9
  # @!macro internal_implementation_note
@@ -1,3 +1,6 @@
1
+ require 'monitor'
2
+ require 'concurrent/synchronization/mutex_object'
3
+
1
4
  module Concurrent
2
5
  module Synchronization
3
6
 
@@ -1,3 +1,8 @@
1
+ require 'concurrent/synchronization/java_object'
2
+ require 'concurrent/synchronization/monitor_object'
3
+ require 'concurrent/synchronization/mutex_object'
4
+ require 'concurrent/synchronization/rbx_object'
5
+
1
6
  module Concurrent
2
7
  module Synchronization
3
8
 
@@ -2,35 +2,48 @@ module Concurrent
2
2
  module Synchronization
3
3
 
4
4
  if Concurrent.on_rbx?
5
-
5
+
6
6
  # @!visibility private
7
7
  # @!macro internal_implementation_note
8
8
  class RbxObject < AbstractObject
9
9
  def initialize
10
- @Waiters = []
10
+ @__Waiters__ = []
11
+ @__owner__ = nil
11
12
  ensure_ivar_visibility!
12
13
  end
13
14
 
14
15
  protected
15
16
 
16
17
  def synchronize(&block)
17
- Rubinius.synchronize(self, &block)
18
+ if @__owner__ == Thread.current
19
+ yield
20
+ else
21
+ Rubinius.lock(self)
22
+ begin
23
+ @__owner__ = Thread.current
24
+ result = yield
25
+ ensure
26
+ @__owner__ = nil
27
+ Rubinius.unlock(self)
28
+ result
29
+ end
30
+ end
18
31
  end
19
32
 
20
33
  def ns_wait(timeout = nil)
21
34
  wchan = Rubinius::Channel.new
22
35
 
23
36
  begin
24
- @Waiters.push wchan
37
+ @__Waiters__.push wchan
25
38
  Rubinius.unlock(self)
26
39
  signaled = wchan.receive_timeout timeout
27
40
  ensure
28
41
  Rubinius.lock(self)
29
42
 
30
- if !signaled && !@Waiters.delete(wchan)
43
+ if !signaled && !@__Waiters__.delete(wchan)
31
44
  # we timed out, but got signaled afterwards,
32
45
  # so pass that signal on to the next waiter
33
- @Waiters.shift << true unless @Waiters.empty?
46
+ @__Waiters__.shift << true unless @__Waiters__.empty?
34
47
  end
35
48
  end
36
49
 
@@ -38,12 +51,12 @@ module Concurrent
38
51
  end
39
52
 
40
53
  def ns_signal
41
- @Waiters.shift << true unless @Waiters.empty?
54
+ @__Waiters__.shift << true unless @__Waiters__.empty?
42
55
  self
43
56
  end
44
57
 
45
58
  def ns_broadcast
46
- @Waiters.shift << true until @Waiters.empty?
59
+ @__Waiters__.shift << true until @__Waiters__.empty?
47
60
  self
48
61
  end
49
62
 
@@ -1,4 +1,4 @@
1
- require 'concurrent/concern/logging'
1
+ require 'logger'
2
2
  require 'concurrent/synchronization'
3
3
 
4
4
  module Concurrent
@@ -8,11 +8,11 @@ module Concurrent
8
8
  #
9
9
  # @!visibility private
10
10
  class AtExitImplementation < Synchronization::Object
11
- include Concern::Logging
11
+ include Logger::Severity
12
12
 
13
13
  def initialize(*args)
14
14
  super()
15
- synchronize { ns_initialize *args }
15
+ synchronize { ns_initialize(*args) }
16
16
  end
17
17
 
18
18
  # Add a handler to be run at `Kernel#at_exit`
@@ -46,9 +46,9 @@ module Concurrent
46
46
  def install
47
47
  synchronize do
48
48
  @installed ||= begin
49
- at_exit { runner }
50
- true
51
- end
49
+ at_exit { runner }
50
+ true
51
+ end
52
52
  self
53
53
  end
54
54
  end
@@ -71,7 +71,7 @@ module Concurrent
71
71
  begin
72
72
  handler.call
73
73
  rescue => error
74
- log ERROR, error
74
+ Concurrent.global_logger.call(ERROR, error)
75
75
  end
76
76
  end
77
77
  handlers.keys
@@ -19,6 +19,10 @@ module Concurrent
19
19
  ruby_engine == 'rbx'
20
20
  end
21
21
 
22
+ def on_windows?
23
+ !(RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/).nil?
24
+ end
25
+
22
26
  def ruby_engine
23
27
  defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
24
28
  end
@@ -25,9 +25,6 @@ module Concurrent
25
25
  # may be a Windows cross-compiled native gem
26
26
  require "concurrent/#{RUBY_VERSION[0..2]}/extension"
27
27
  @c_ext_loaded = true
28
- end,
29
- lambda do
30
- warn 'Performance on MRI may be improved with the concurrent-ruby-ext gem. Please see http://concurrent-ruby.com'
31
28
  end]
32
29
 
33
30
  tries.each do |try|
@@ -45,7 +42,7 @@ module Concurrent
45
42
  require 'concurrent_ruby_ext'
46
43
  @java_ext_loaded = true
47
44
  rescue LoadError
48
- warn 'Performance on JRuby may be improved by installing the pre-compiled Java extensions. Please see http://concurrent-ruby.com'
45
+ # move on with pure-Ruby implementations
49
46
  end
50
47
  end
51
48
  end