concurrent-ruby 0.9.0.pre2 → 0.9.0.pre3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e100cda902e2d18d80d34e38ec541d11bde399a
4
- data.tar.gz: a56ad16d5a76aa677befbdf3ad2f7b47b0cc1fcb
3
+ metadata.gz: f405da05002f7882b78a16748dba3c9a3439bb8f
4
+ data.tar.gz: be024ee9c4ecc15d86840b3599158d2312273459
5
5
  SHA512:
6
- metadata.gz: 066dcc901e922bb751c79acf6249b693984cda1674adf40efc7dbdd782ca22ff8f313dd4674d282b9b22721522ab03aa481c93399fc94017cc8d90a4c17e2acf
7
- data.tar.gz: 36d5fe13bebec7e07b3639c65deb455d0bbcb091a11678c05c8664213573179117517d3f2f097d6413a9f71fc09e1193b8ec189ccaa6d1c422779994638015cd
6
+ metadata.gz: a1c334847abed2ba6b9b3dbd290b4aa137ccdad02dd1f11aaa4b5fff6ce64cf37ce197ff2dc6ec5ad580053cf65ce38df7334e69ca54dd26f53dfa782654dacb
7
+ data.tar.gz: ab7cd113db8ee277fa8fda122cdc6efc74e2c245f4614016e2e3c4fcbd6f4c1ca55dd65adb42fa9cec0d08752971774579af3ffc4758054be12b3e0022a63638
@@ -1,5 +1,10 @@
1
1
  ### Next Release v0.9.0 (Target Date: 7 June 2015)
2
2
 
3
+
4
+ * Updated `AtomicReference`
5
+ - `AtomicReference#try_update` now simply returns instead of raising exception
6
+ - `AtomicReference#try_update!` was added to raise exceptions if an update
7
+ fails. Note: this is the same behavior as the old `try_update`
3
8
  * Pure Java implementations of
4
9
  - `AtomicBoolean`
5
10
  - `AtomicFixnum`
@@ -58,7 +63,7 @@
58
63
  - `Channel`
59
64
  - `Exchanger`
60
65
  - `LazyRegister`
61
- - **new Future Framework** <http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html> - unified
66
+ - **new Future Framework** <http://ruby-concurrency.github.io/concurrent-ruby/Concurrent/Edge.html> - unified
62
67
  implementation of Futures and Promises which combines Features of previous `Future`,
63
68
  `Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively
64
69
  new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`.
@@ -80,7 +85,7 @@
80
85
  - Add AbstractContext#default_executor to be able to override executor class wide
81
86
  - Add basic IO example
82
87
  - Documentation somewhat improved
83
- - All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and
88
+ - All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and
84
89
  be sure that both jobs are processed first.
85
90
  * Refactored `Channel` to use newer synchronization objects
86
91
  * Added `#reset` and `#cancel` methods to `TimerSet`
@@ -162,7 +167,7 @@ Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/iss
162
167
  - `SerializedExecutionDelegator` for serializing *any* executor
163
168
  * Updated `Async` with serialized execution
164
169
  * Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle
165
- * Added a `Delay` to root `Actress` initialization
170
+ * Added a `Delay` to root `Actress` initialization
166
171
  * Minor bug fixes to thread pools
167
172
  * Refactored many intermittently failing specs
168
173
  * Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)`
@@ -49,6 +49,62 @@ require 'concurrent/tvar'
49
49
  #
50
50
  # @see http://linux.die.net/man/3/clock_gettime Linux clock_gettime(3)
51
51
 
52
+ # @!macro [new] copy_options
53
+ #
54
+ # ## Copy Options
55
+ #
56
+ # Object references in Ruby are mutable. This can lead to serious
57
+ # problems when the {#value} of an object is a mutable reference. Which
58
+ # is always the case unless the value is a `Fixnum`, `Symbol`, or similar
59
+ # "primative" data type. Each instance can be configured with a few
60
+ # options that can help protect the program from potentially dangerous
61
+ # operations. Each of these options can be optionally set when the oject
62
+ # instance is created:
63
+ #
64
+ # * `:dup_on_deref` When true the object will call the `#dup` method on
65
+ # the `value` object every time the `#value` methid is called
66
+ # (default: false)
67
+ # * `:freeze_on_deref` When true the object will call the `#freeze`
68
+ # method on the `value` object every time the `#value` method is called
69
+ # (default: false)
70
+ # * `:copy_on_deref` When given a `Proc` object the `Proc` will be run
71
+ # every time the `#value` method is called. The `Proc` will be given
72
+ # the current `value` as its only argument and the result returned by
73
+ # the block will be the return value of the `#value` call. When `nil`
74
+ # this option will be ignored (default: nil)
75
+ #
76
+ # When multiple deref options are set the order of operations is strictly defined.
77
+ # The order of deref operations is:
78
+ # * `:copy_on_deref`
79
+ # * `:dup_on_deref`
80
+ # * `:freeze_on_deref`
81
+ #
82
+ # Because of this ordering there is no need to `#freeze` an object created by a
83
+ # provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`.
84
+ # Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is
85
+ # as close to the behavior of a "pure" functional language (like Erlang, Clojure,
86
+ # or Haskell) as we are likely to get in Ruby.
87
+
88
+ # @!macro [attach] deref_options
89
+ #
90
+ # @option opts [Boolean] :dup_on_deref (false) Call `#dup` before
91
+ # returning the data from {#value}
92
+ # @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before
93
+ # returning the data from {#value}
94
+ # @option opts [Proc] :copy_on_deref (nil) When calling the {#value}
95
+ # method, call the given proc passing the internal value as the sole
96
+ # argument then return the new value returned from the proc.
97
+
98
+ # @!macro [attach] executor_and_deref_options
99
+ #
100
+ # @param [Hash] opts the options used to define the behavior at update and deref
101
+ # and to specify the executor on which to perform actions
102
+ # @option opts [Executor] :executor when set use the given `Executor` instance.
103
+ # Three special values are also supported: `:task` returns the global task pool,
104
+ # `:operation` returns the global operation pool, and `:immediate` returns a new
105
+ # `ImmediateExecutor` object.
106
+ # @!macro deref_options
107
+
52
108
  # Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
53
109
  # F#, C#, Java, and classic concurrency patterns.
54
110
  #
@@ -5,6 +5,7 @@ require 'concurrent/errors'
5
5
  require 'concurrent/ivar'
6
6
  require 'concurrent/executor/immediate_executor'
7
7
  require 'concurrent/executor/serialized_execution'
8
+ require 'concurrent/concern/deprecation'
8
9
 
9
10
  module Concurrent
10
11
 
@@ -30,23 +31,12 @@ module Concurrent
30
31
  # object. The former method allows methods to be called asynchronously by posting
31
32
  # to the global thread pool. The latter allows a method to be called synchronously
32
33
  # on the current thread but does so safely with respect to any pending asynchronous
33
- # method calls. Both methods return an `Obligation` which can be inspected for
34
+ # method calls. Both methods return an `IVar` which can be inspected for
34
35
  # the result of the method call. Calling a method with `async` will return a
35
- # `:pending` `Obligation` whereas `await` will return a `:complete` `Obligation`.
36
+ # `:pending` `IVar` whereas `await` will return a `:complete` `IVar`.
36
37
  #
37
38
  # Very loosely based on the `async` and `await` keywords in C#.
38
39
  #
39
- # ### An Important Note About Initialization
40
- #
41
- # > This module depends on several internal stnchronization mechanisms that
42
- # > must be initialized prior to calling any of the async/await/executor methods.
43
- # > To ensure thread-safe initialization the class `new` method will be made
44
- # > private when the `Concurrent::Async` module is included. A factory method
45
- # > called `create` will be defined in its place. The `create`factory will
46
- # > create a new object instance, passing all arguments to the constructor,
47
- # > and will initialize all stnchronization mechanisms. This is the only way
48
- # > thread-safe initialization can be guaranteed.
49
- #
50
40
  # ### An Important Note About Thread Safe Guarantees
51
41
  #
52
42
  # > Thread safe guarantees can only be made when asynchronous method calls
@@ -70,23 +60,19 @@ module Concurrent
70
60
  # nil
71
61
  # end
72
62
  # end
73
- #
74
- # horn = Echo.new #=> NoMethodError: private method `new' called for Echo:Class
75
63
  #
76
- # horn = Echo.create
64
+ # horn = Echo.new
77
65
  # horn.echo('zero') # synchronous, not thread-safe
78
66
  #
79
67
  # horn.async.echo('one') # asynchronous, non-blocking, thread-safe
80
68
  # horn.await.echo('two') # synchronous, blocking, thread-safe
81
69
  #
82
- # @see Concurrent::Concern::Obligation
83
70
  # @see Concurrent::IVar
84
71
  module Async
85
72
 
86
- # @!method self.create(*args, &block)
73
+ # @!method self.new(*args, &block)
87
74
  #
88
- # The factory method used to create new instances of the asynchronous
89
- # class. Used instead of `new` to ensure proper initialization of the
75
+ # Instanciate a new object and ensure proper initialization of the
90
76
  # synchronization mechanisms.
91
77
  #
92
78
  # @param [Array<Object>] args Zero or more arguments to be passed to the
@@ -129,21 +115,13 @@ module Concurrent
129
115
  # @!visibility private
130
116
  def self.included(base)
131
117
  base.singleton_class.send(:alias_method, :original_new, :new)
132
- base.send(:private_class_method, :original_new)
133
118
  base.extend(ClassMethods)
134
119
  super(base)
135
120
  end
136
121
 
137
122
  # @!visibility private
138
123
  module ClassMethods
139
-
140
- # @deprecated
141
124
  def new(*args, &block)
142
- warn '[DEPRECATED] use the `create` method instead'
143
- create(*args, &block)
144
- end
145
-
146
- def create(*args, &block)
147
125
  obj = original_new(*args, &block)
148
126
  obj.send(:init_synchronization)
149
127
  obj
@@ -280,7 +258,7 @@ module Concurrent
280
258
  # @!visibility private
281
259
  # @deprecated
282
260
  def init_mutex
283
- warn '[DEPRECATED] use the `create` method instead'
261
+ deprecated 'mutex synchronization now happens automatically'
284
262
  init_synchronization
285
263
  rescue InitializationError
286
264
  # suppress
@@ -18,40 +18,7 @@ module Concurrent
18
18
  # new value to the result of running the given block if and only if that
19
19
  # value validates.
20
20
  #
21
- # @!macro [attach] copy_options
22
- # ## Copy Options
23
- #
24
- # Object references in Ruby are mutable. This can lead to serious
25
- # problems when the {#value} of an object is a mutable reference. Which
26
- # is always the case unless the value is a `Fixnum`, `Symbol`, or similar
27
- # "primative" data type. Each instance can be configured with a few
28
- # options that can help protect the program from potentially dangerous
29
- # operations. Each of these options can be optionally set when the oject
30
- # instance is created:
31
- #
32
- # * `:dup_on_deref` When true the object will call the `#dup` method on
33
- # the `value` object every time the `#value` methid is called
34
- # (default: false)
35
- # * `:freeze_on_deref` When true the object will call the `#freeze`
36
- # method on the `value` object every time the `#value` method is called
37
- # (default: false)
38
- # * `:copy_on_deref` When given a `Proc` object the `Proc` will be run
39
- # every time the `#value` method is called. The `Proc` will be given
40
- # the current `value` as its only argument and the result returned by
41
- # the block will be the return value of the `#value` call. When `nil`
42
- # this option will be ignored (default: nil)
43
- #
44
- # When multiple deref options are set the order of operations is strictly defined.
45
- # The order of deref operations is:
46
- # * `:copy_on_deref`
47
- # * `:dup_on_deref`
48
- # * `:freeze_on_deref`
49
- #
50
- # Because of this ordering there is no need to `#freeze` an object created by a
51
- # provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`.
52
- # Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is
53
- # as close to the behavior of a "pure" functional language (like Erlang, Clojure,
54
- # or Haskell) as we are likely to get in Ruby.
21
+ # @!macro copy_options
55
22
  #
56
23
  # @see http://clojure.org/atoms Clojure Atoms
57
24
  class Atom < Synchronization::Object
@@ -66,14 +33,7 @@ module Concurrent
66
33
  # intended new value. The validator will return true if the new value
67
34
  # is acceptable else return false (preferrably) or raise an exception.
68
35
  #
69
- # @!macro [attach] deref_options
70
- # @option opts [Boolean] :dup_on_deref (false) Call `#dup` before
71
- # returning the data from {#value}
72
- # @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before
73
- # returning the data from {#value}
74
- # @option opts [Proc] :copy_on_deref (nil) When calling the {#value}
75
- # method, call the given proc passing the internal value as the sole
76
- # argument then return the new value returned from the proc.
36
+ # @!macro deref_options
77
37
  #
78
38
  # @raise [ArgumentError] if the validator is not a `Proc` (when given)
79
39
  def initialize(value, opts = {})
@@ -13,7 +13,7 @@ module Concurrent
13
13
  # Pass the current value to the given block, replacing it
14
14
  # with the block's result. May retry if the value changes
15
15
  # during the block's execution.
16
- #
16
+ #
17
17
  # @yield [Object] Calculate a new value for the atomic reference using
18
18
  # given (old) value
19
19
  # @yieldparam [Object] old_value the starting value of the atomic reference
@@ -27,17 +27,45 @@ module Concurrent
27
27
  # @!macro [attach] atomic_reference_method_try_update
28
28
  #
29
29
  # Pass the current value to the given block, replacing it
30
+ # with the block's result. Return nil if the update fails.
31
+ #
32
+ # @yield [Object] Calculate a new value for the atomic reference using
33
+ # given (old) value
34
+ # @yieldparam [Object] old_value the starting value of the atomic reference
35
+ #
36
+ # @note This method was altered to avoid raising an exception by default.
37
+ # Instead, this method now returns `nil` in case of failure. For more info,
38
+ # please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
39
+ #
40
+ # @return [Object] the new value, or nil if update failed
41
+ def try_update
42
+ old_value = get
43
+ new_value = yield old_value
44
+
45
+ return unless compare_and_set old_value, new_value
46
+
47
+ new_value
48
+ end
49
+
50
+ # @!macro [attach] atomic_reference_method_try_update!
51
+ #
52
+ # Pass the current value to the given block, replacing it
30
53
  # with the block's result. Raise an exception if the update
31
54
  # fails.
32
- #
55
+ #
33
56
  # @yield [Object] Calculate a new value for the atomic reference using
34
57
  # given (old) value
35
58
  # @yieldparam [Object] old_value the starting value of the atomic reference
36
59
  #
60
+ # @note This behavior mimics the behavior of the original
61
+ # `AtomicReference#try_update` API. The reason this was changed was to
62
+ # avoid raising exceptions (which are inherently slow) by default. For more
63
+ # info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336
64
+ #
37
65
  # @return [Object] the new value
38
66
  #
39
67
  # @raise [Concurrent::ConcurrentUpdateError] if the update fails
40
- def try_update
68
+ def try_update!
41
69
  old_value = get
42
70
  new_value = yield old_value
43
71
  unless compare_and_set(old_value, new_value)
@@ -42,14 +42,14 @@ module Concurrent
42
42
 
43
43
  # @!macro atomic_reference_method_compare_and_set
44
44
  def _compare_and_set(old_value, new_value)
45
- return false unless @mutex.try_lock
46
- begin
47
- return false unless @value.equal? old_value
48
- @value = new_value
49
- ensure
50
- @mutex.unlock
45
+ @mutex.synchronize do
46
+ if @value.equal? old_value
47
+ @value = new_value
48
+ true
49
+ else
50
+ false
51
+ end
51
52
  end
52
- true
53
53
  end
54
54
  end
55
55
  end
@@ -73,11 +73,10 @@ module Concurrent
73
73
  end
74
74
  end
75
75
 
76
- # Disables AtExit hooks including pool auto-termination hooks.
77
- # When disabled it will be the application
78
- # programmer's responsibility to ensure that the hooks
79
- # are shutdown properly prior to application exit
80
- # by calling {AtExit.run} method.
76
+ # Disables AtExit handlers including pool auto-termination handlers.
77
+ # When disabled it will be the application programmer's responsibility
78
+ # to ensure that the handlers are shutdown properly prior to application
79
+ # exit by calling {AtExit.run} method.
81
80
  #
82
81
  # @note this option should be needed only because of `at_exit` ordering
83
82
  # issues which may arise when running some of the testing frameworks.
@@ -88,13 +87,13 @@ module Concurrent
88
87
  # from within a gem. It should *only* be used from within the main
89
88
  # application and even then it should be used only when necessary.
90
89
  # @see AtExit
91
- def self.disable_at_exit_hooks!
90
+ def self.disable_at_exit_handlers!
92
91
  AtExit.enabled = false
93
92
  end
94
93
 
95
94
  def self.disable_executor_auto_termination!
96
- deprecated_method 'disable_executor_auto_termination!', 'disable_at_exit_hooks!'
97
- disable_at_exit_hooks!
95
+ deprecated_method 'disable_executor_auto_termination!', 'disable_at_exit_handlers!'
96
+ disable_at_exit_handlers!
98
97
  end
99
98
 
100
99
  # @return [true,false]
@@ -132,8 +131,6 @@ module Concurrent
132
131
  # Global thread pool user for global *timers*.
133
132
  #
134
133
  # @return [Concurrent::TimerSet] the thread pool
135
- #
136
- # @see Concurrent::timer
137
134
  def self.global_timer_set
138
135
  GLOBAL_TIMER_SET.value
139
136
  end
@@ -249,10 +246,10 @@ module Concurrent
249
246
  Concurrent.new_fast_executor
250
247
  end
251
248
 
252
- # @deprecated Use Concurrent.disable_auto_termination_of_global_executors! instead
249
+ # @deprecated Use Concurrent.disable_executor_auto_termination! instead
253
250
  def auto_terminate=(value)
254
- deprecated_method 'Concurrent.configuration.auto_terminate=', 'Concurrent.disable_auto_termination_of_global_executors!'
255
- Concurrent.disable_auto_termination_of_global_executors! if !value
251
+ deprecated_method 'Concurrent.configuration.auto_terminate=', 'Concurrent.disable_executor_auto_termination!'
252
+ Concurrent.disable_executor_auto_termination! if !value
256
253
  end
257
254
 
258
255
  # @deprecated Use Concurrent.auto_terminate_global_executors? instead
@@ -21,10 +21,10 @@ module Concurrent
21
21
  #
22
22
  # @!macro [attach] edge_warning
23
23
  # @api Edge
24
- # @note **Edge Feature:** Edge features are under active development and may
25
- # change frequently. They are not expected to keep backward compatibility.
26
- # They may also lack tests and documentation. Use with caution.
24
+ # @note **Edge Feature:** Edge features are under active development and may change frequently. They are expected not to
25
+ # keep backward compatibility (there may also lack tests and documentation). Semantic versions will
26
+ # be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move
27
+ # to `concurrent-ruby` when final.
27
28
  module Edge
28
-
29
29
  end
30
30
  end
@@ -1,40 +1,42 @@
1
1
  module Concurrent
2
2
 
3
+ Error = Class.new(StandardError)
4
+
3
5
  # Raised when errors occur during configuration.
4
- ConfigurationError = Class.new(StandardError)
6
+ ConfigurationError = Class.new(Error)
5
7
 
6
8
  # Raised when an asynchronous operation is cancelled before execution.
7
- CancelledOperationError = Class.new(StandardError)
9
+ CancelledOperationError = Class.new(Error)
8
10
 
9
11
  # Raised when a lifecycle method (such as `stop`) is called in an improper
10
12
  # sequence or when the object is in an inappropriate state.
11
- LifecycleError = Class.new(StandardError)
13
+ LifecycleError = Class.new(Error)
12
14
 
13
15
  # Raised when an attempt is made to violate an immutability guarantee.
14
- ImmutabilityError = Class.new(StandardError)
16
+ ImmutabilityError = Class.new(Error)
15
17
 
16
18
  # Raised when an object's methods are called when it has not been
17
19
  # properly initialized.
18
- InitializationError = Class.new(StandardError)
20
+ InitializationError = Class.new(Error)
19
21
 
20
22
  # Raised when an object with a start/stop lifecycle has been started an
21
23
  # excessive number of times. Often used in conjunction with a restart
22
24
  # policy or strategy.
23
- MaxRestartFrequencyError = Class.new(StandardError)
25
+ MaxRestartFrequencyError = Class.new(Error)
24
26
 
25
27
  # Raised when an attempt is made to modify an immutable object
26
28
  # (such as an `IVar`) after its final state has been set.
27
- MultipleAssignmentError = Class.new(StandardError)
29
+ MultipleAssignmentError = Class.new(Error)
28
30
 
29
31
  # Raised by an `Executor` when it is unable to process a given task,
30
32
  # possibly because of a reject policy or other internal error.
31
- RejectedExecutionError = Class.new(StandardError)
33
+ RejectedExecutionError = Class.new(Error)
32
34
 
33
35
  # Raised when any finite resource, such as a lock counter, exceeds its
34
36
  # maximum limit/threshold.
35
- ResourceLimitError = Class.new(StandardError)
37
+ ResourceLimitError = Class.new(Error)
36
38
 
37
39
  # Raised when an operation times out.
38
- TimeoutError = Class.new(StandardError)
40
+ TimeoutError = Class.new(Error)
39
41
 
40
42
  end
@@ -1,46 +1,32 @@
1
- require 'concurrent/executor/ruby_cached_thread_pool'
1
+ require 'concurrent/utility/engine'
2
+ require 'concurrent/executor/thread_pool_executor'
2
3
 
3
4
  module Concurrent
4
5
 
5
- if Concurrent.on_jruby?
6
- require 'concurrent/executor/java_cached_thread_pool'
7
- end
8
-
9
- CachedThreadPoolImplementation = case
10
- when Concurrent.on_jruby?
11
- JavaCachedThreadPool
12
- else
13
- RubyCachedThreadPool
14
- end
15
- private_constant :CachedThreadPoolImplementation
16
-
17
- # @!macro [attach] cached_thread_pool
6
+ # A thread pool that dynamically grows and shrinks to fit the current workload.
7
+ # New threads are created as needed, existing threads are reused, and threads
8
+ # that remain idle for too long are killed and removed from the pool. These
9
+ # pools are particularly suited to applications that perform a high volume of
10
+ # short-lived tasks.
18
11
  #
19
- # A thread pool that dynamically grows and shrinks to fit the current workload.
20
- # New threads are created as needed, existing threads are reused, and threads
21
- # that remain idle for too long are killed and removed from the pool. These
22
- # pools are particularly suited to applications that perform a high volume of
23
- # short-lived tasks.
12
+ # On creation a `CachedThreadPool` has zero running threads. New threads are
13
+ # created on the pool as new operations are `#post`. The size of the pool
14
+ # will grow until `#max_length` threads are in the pool or until the number
15
+ # of threads exceeds the number of running and pending operations. When a new
16
+ # operation is post to the pool the first available idle thread will be tasked
17
+ # with the new operation.
24
18
  #
25
- # On creation a `CachedThreadPool` has zero running threads. New threads are
26
- # created on the pool as new operations are `#post`. The size of the pool
27
- # will grow until `#max_length` threads are in the pool or until the number
28
- # of threads exceeds the number of running and pending operations. When a new
29
- # operation is post to the pool the first available idle thread will be tasked
30
- # with the new operation.
19
+ # Should a thread crash for any reason the thread will immediately be removed
20
+ # from the pool. Similarly, threads which remain idle for an extended period
21
+ # of time will be killed and reclaimed. Thus these thread pools are very
22
+ # efficient at reclaiming unused resources.
31
23
  #
32
- # Should a thread crash for any reason the thread will immediately be removed
33
- # from the pool. Similarly, threads which remain idle for an extended period
34
- # of time will be killed and reclaimed. Thus these thread pools are very
35
- # efficient at reclaiming unused resources.
36
- #
37
- # The API and behavior of this class are based on Java's `CachedThreadPool`
24
+ # The API and behavior of this class are based on Java's `CachedThreadPool`
38
25
  #
39
26
  # @!macro thread_pool_options
40
- # @!macro thread_pool_executor_public_api
41
- class CachedThreadPool < CachedThreadPoolImplementation
27
+ class CachedThreadPool < ThreadPoolExecutor
42
28
 
43
- # @!macro [new] cached_thread_pool_method_initialize
29
+ # @!macro [attach] cached_thread_pool_method_initialize
44
30
  #
45
31
  # Create a new thread pool.
46
32
  #
@@ -50,8 +36,27 @@ module Concurrent
50
36
  # @raise [ArgumentError] if `fallback_policy` is not a known policy
51
37
  #
52
38
  # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool--
39
+ def initialize(opts = {})
40
+ defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT }
41
+ overrides = { min_threads: 0,
42
+ max_threads: DEFAULT_MAX_POOL_SIZE,
43
+ max_queue: DEFAULT_MAX_QUEUE_SIZE }
44
+ super(defaults.merge(opts).merge(overrides))
45
+ end
46
+
47
+ private
53
48
 
54
- # @!method initialize(opts = {})
55
- # @!macro cached_thread_pool_method_initialize
49
+ # @!macro cached_thread_pool_method_initialize
50
+ # @!visibility private
51
+ def ns_initialize(opts)
52
+ super(opts)
53
+ if Concurrent.on_jruby?
54
+ @max_queue = 0
55
+ @executor = java.util.concurrent.Executors.newCachedThreadPool
56
+ @executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new)
57
+ @executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS)
58
+ self.auto_terminate = opts.fetch(:auto_terminate, true)
59
+ end
60
+ end
56
61
  end
57
62
  end
@@ -1,19 +1,8 @@
1
- require 'concurrent/executor/ruby_fixed_thread_pool'
1
+ require 'concurrent/utility/engine'
2
+ require 'concurrent/executor/thread_pool_executor'
2
3
 
3
4
  module Concurrent
4
5
 
5
- if Concurrent.on_jruby?
6
- require 'concurrent/executor/java_fixed_thread_pool'
7
- end
8
-
9
- FixedThreadPoolImplementation = case
10
- when Concurrent.on_jruby?
11
- JavaFixedThreadPool
12
- else
13
- RubyFixedThreadPool
14
- end
15
- private_constant :FixedThreadPoolImplementation
16
-
17
6
  # @!macro [new] thread_pool_executor_constant_default_max_pool_size
18
7
  # Default maximum number of threads that will be created in the pool.
19
8
 
@@ -119,35 +108,7 @@ module Concurrent
119
108
 
120
109
 
121
110
 
122
-
123
- # @!macro [new] fixed_thread_pool_method_initialize
124
- #
125
- # Create a new thread pool.
126
- #
127
- # @param [Integer] num_threads the number of threads to allocate
128
- # @param [Hash] opts the options defining pool behavior.
129
- # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy
130
- #
131
- # @raise [ArgumentError] if `num_threads` is less than or equal to zero
132
- # @raise [ArgumentError] if `fallback_policy` is not a known policy
133
- #
134
- # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-
135
-
136
-
137
-
138
-
139
-
140
- # @!macro [attach] fixed_thread_pool
141
- #
142
- # A thread pool with a set number of threads. The number of threads in the pool
143
- # is set on construction and remains constant. When all threads are busy new
144
- # tasks `#post` to the thread pool are enqueued until a thread becomes available.
145
- # Should a thread crash for any reason the thread will immediately be removed
146
- # from the pool and replaced.
147
- #
148
- # The API and behavior of this class are based on Java's `FixedThreadPool`
149
- #
150
- # @!macro [attach] thread_pool_options
111
+ # @!macro [new] thread_pool_options
151
112
  #
152
113
  # **Thread Pool Options**
153
114
  #
@@ -203,11 +164,43 @@ module Concurrent
203
164
  # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class
204
165
  # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface
205
166
  # @see http://ruby-doc.org//core-2.2.0/Kernel.html#method-i-at_exit Kernel#at_exit
206
- #
207
- # @!macro thread_pool_executor_public_api
208
- class FixedThreadPool < FixedThreadPoolImplementation
209
167
 
210
- # @!method initialize(num_threads, opts = {})
211
- # @!macro fixed_thread_pool_method_initialize
168
+
169
+
170
+
171
+
172
+ # @!macro [attach] fixed_thread_pool
173
+ #
174
+ # A thread pool with a set number of threads. The number of threads in the pool
175
+ # is set on construction and remains constant. When all threads are busy new
176
+ # tasks `#post` to the thread pool are enqueued until a thread becomes available.
177
+ # Should a thread crash for any reason the thread will immediately be removed
178
+ # from the pool and replaced.
179
+ #
180
+ # The API and behavior of this class are based on Java's `FixedThreadPool`
181
+ #
182
+ # @!macro thread_pool_options
183
+ class FixedThreadPool < ThreadPoolExecutor
184
+
185
+ # @!macro [attach] fixed_thread_pool_method_initialize
186
+ #
187
+ # Create a new thread pool.
188
+ #
189
+ # @param [Integer] num_threads the number of threads to allocate
190
+ # @param [Hash] opts the options defining pool behavior.
191
+ # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy
192
+ #
193
+ # @raise [ArgumentError] if `num_threads` is less than or equal to zero
194
+ # @raise [ArgumentError] if `fallback_policy` is not a known policy
195
+ #
196
+ # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-
197
+ def initialize(num_threads, opts = {})
198
+ raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1
199
+ defaults = { max_queue: DEFAULT_MAX_QUEUE_SIZE,
200
+ idletime: DEFAULT_THREAD_IDLETIMEOUT }
201
+ overrides = { min_threads: num_threads,
202
+ max_threads: num_threads }
203
+ super(defaults.merge(opts).merge(overrides))
204
+ end
212
205
  end
213
206
  end
@@ -1,3 +1,4 @@
1
+ require 'concurrent/utility/engine'
1
2
  require 'concurrent/executor/ruby_thread_pool_executor'
2
3
 
3
4
  module Concurrent
@@ -34,7 +34,7 @@ module Concurrent
34
34
  # ```ruby
35
35
  # ivar = Concurrent::IVar.new
36
36
  # ivar.set 14
37
- # ivar.get #=> 14
37
+ # ivar.value #=> 14
38
38
  # ivar.set 2 # would now be an error
39
39
  # ```
40
40
  #
@@ -297,13 +297,14 @@ module Concurrent
297
297
 
298
298
  # @!visibility private
299
299
  def schedule_next_task(interval = execution_interval)
300
- Concurrent::timer(interval, Concurrent::Event.new, &method(:execute_task))
300
+ ScheduledTask.execute(interval, args: [Concurrent::Event.new], &method(:execute_task))
301
+ nil
301
302
  end
302
303
 
303
304
  # @!visibility private
304
305
  def execute_task(completion)
305
- return unless @running.true?
306
- Concurrent::timer(execution_interval, completion, &method(:timeout_task))
306
+ return nil unless @running.true?
307
+ ScheduledTask.execute(execution_interval, args: [completion], &method(:timeout_task))
307
308
  _success, value, reason = @executor.execute(self)
308
309
  if completion.try?
309
310
  self.value = value
@@ -313,6 +314,7 @@ module Concurrent
313
314
  [time, self.value, reason]
314
315
  end
315
316
  end
317
+ nil
316
318
  end
317
319
 
318
320
  # @!visibility private
@@ -1,4 +1,4 @@
1
1
  module Concurrent
2
- VERSION = '0.9.0.pre2'
3
- EDGE_VERSION = '0.1.0.pre2'
2
+ VERSION = '0.9.0.pre3'
3
+ EDGE_VERSION = '0.1.0.pre3'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concurrent-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0.pre2
4
+ version: 0.9.0.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jerry D'Antonio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-08 00:00:00.000000000 Z
12
+ date: 2015-06-22 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: |
15
15
  Modern concurrency tools including agents, futures, promises, thread pools, actors, supervisors, and more.
@@ -69,12 +69,8 @@ files:
69
69
  - lib/concurrent/executor/fixed_thread_pool.rb
70
70
  - lib/concurrent/executor/immediate_executor.rb
71
71
  - lib/concurrent/executor/indirect_immediate_executor.rb
72
- - lib/concurrent/executor/java_cached_thread_pool.rb
73
- - lib/concurrent/executor/java_fixed_thread_pool.rb
74
72
  - lib/concurrent/executor/java_single_thread_executor.rb
75
73
  - lib/concurrent/executor/java_thread_pool_executor.rb
76
- - lib/concurrent/executor/ruby_cached_thread_pool.rb
77
- - lib/concurrent/executor/ruby_fixed_thread_pool.rb
78
74
  - lib/concurrent/executor/ruby_single_thread_executor.rb
79
75
  - lib/concurrent/executor/ruby_thread_pool_executor.rb
80
76
  - lib/concurrent/executor/safe_task_executor.rb
@@ -136,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
132
  version: 1.3.1
137
133
  requirements: []
138
134
  rubyforge_project:
139
- rubygems_version: 2.4.7
135
+ rubygems_version: 2.4.8
140
136
  signing_key:
141
137
  specification_version: 4
142
138
  summary: Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell,
@@ -1,34 +0,0 @@
1
- if Concurrent.on_jruby?
2
-
3
- require 'concurrent/executor/java_thread_pool_executor'
4
-
5
- module Concurrent
6
-
7
- # @!macro cached_thread_pool
8
- # @!macro thread_pool_options
9
- # @!macro thread_pool_executor_public_api
10
- # @!visibility private
11
- class JavaCachedThreadPool < JavaThreadPoolExecutor
12
-
13
- # @!macro cached_thread_pool_method_initialize
14
- def initialize(opts = {})
15
- defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT }
16
- overrides = { min_threads: 0,
17
- max_threads: DEFAULT_MAX_POOL_SIZE,
18
- max_queue: 0 }
19
- super(defaults.merge(opts).merge(overrides))
20
- end
21
-
22
- protected
23
-
24
- def ns_initialize(opts)
25
- super(opts)
26
- @max_queue = 0
27
- @executor = java.util.concurrent.Executors.newCachedThreadPool
28
- @executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new)
29
- @executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS)
30
- self.auto_terminate = opts.fetch(:auto_terminate, true)
31
- end
32
- end
33
- end
34
- end
@@ -1,24 +0,0 @@
1
- if Concurrent.on_jruby?
2
-
3
- require 'concurrent/executor/java_thread_pool_executor'
4
-
5
- module Concurrent
6
-
7
- # @!macro fixed_thread_pool
8
- # @!macro thread_pool_options
9
- # @!macro thread_pool_executor_public_api
10
- # @!visibility private
11
- class JavaFixedThreadPool < JavaThreadPoolExecutor
12
-
13
- # @!macro fixed_thread_pool_method_initialize
14
- def initialize(num_threads, opts = {})
15
- raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1
16
- defaults = { max_queue: DEFAULT_MAX_QUEUE_SIZE,
17
- idletime: DEFAULT_THREAD_IDLETIMEOUT }
18
- overrides = { min_threads: num_threads,
19
- max_threads: num_threads }
20
- super(defaults.merge(opts).merge(overrides))
21
- end
22
- end
23
- end
24
- end
@@ -1,20 +0,0 @@
1
- require 'concurrent/executor/ruby_thread_pool_executor'
2
-
3
- module Concurrent
4
-
5
- # @!macro cached_thread_pool
6
- # @!macro thread_pool_options
7
- # @!macro thread_pool_executor_public_api
8
- # @!visibility private
9
- class RubyCachedThreadPool < RubyThreadPoolExecutor
10
-
11
- # @!macro cached_thread_pool_method_initialize
12
- def initialize(opts = {})
13
- defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT }
14
- overrides = { min_threads: 0,
15
- max_threads: DEFAULT_MAX_POOL_SIZE,
16
- max_queue: DEFAULT_MAX_QUEUE_SIZE }
17
- super(defaults.merge(opts).merge(overrides))
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- require 'concurrent/executor/ruby_thread_pool_executor'
2
-
3
- module Concurrent
4
-
5
- # @!macro fixed_thread_pool
6
- # @!macro thread_pool_options
7
- # @!macro thread_pool_executor_public_api
8
- # @!visibility private
9
- class RubyFixedThreadPool < RubyThreadPoolExecutor
10
-
11
- # @!macro fixed_thread_pool_method_initialize
12
- def initialize(num_threads, opts = {})
13
- raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1
14
- defaults = { max_queue: DEFAULT_MAX_QUEUE_SIZE,
15
- idletime: DEFAULT_THREAD_IDLETIMEOUT }
16
- overrides = { min_threads: num_threads,
17
- max_threads: num_threads }
18
- super(defaults.merge(opts).merge(overrides))
19
- end
20
- end
21
- end