concurrent-ruby 0.7.0.rc0-x64-mingw32

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.
Files changed (95) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +166 -0
  4. data/ext/concurrent_ruby_ext/atomic_reference.c +78 -0
  5. data/ext/concurrent_ruby_ext/atomic_reference.h +12 -0
  6. data/ext/concurrent_ruby_ext/extconf.rb +59 -0
  7. data/ext/concurrent_ruby_ext/rb_concurrent.c +28 -0
  8. data/lib/2.0/concurrent_ruby_ext.so +0 -0
  9. data/lib/concurrent.rb +45 -0
  10. data/lib/concurrent/actress.rb +221 -0
  11. data/lib/concurrent/actress/ad_hoc.rb +20 -0
  12. data/lib/concurrent/actress/context.rb +98 -0
  13. data/lib/concurrent/actress/core.rb +228 -0
  14. data/lib/concurrent/actress/core_delegations.rb +42 -0
  15. data/lib/concurrent/actress/envelope.rb +41 -0
  16. data/lib/concurrent/actress/errors.rb +14 -0
  17. data/lib/concurrent/actress/reference.rb +64 -0
  18. data/lib/concurrent/actress/type_check.rb +48 -0
  19. data/lib/concurrent/agent.rb +232 -0
  20. data/lib/concurrent/async.rb +319 -0
  21. data/lib/concurrent/atomic.rb +46 -0
  22. data/lib/concurrent/atomic/atomic_boolean.rb +157 -0
  23. data/lib/concurrent/atomic/atomic_fixnum.rb +162 -0
  24. data/lib/concurrent/atomic/condition.rb +67 -0
  25. data/lib/concurrent/atomic/copy_on_notify_observer_set.rb +118 -0
  26. data/lib/concurrent/atomic/copy_on_write_observer_set.rb +117 -0
  27. data/lib/concurrent/atomic/count_down_latch.rb +116 -0
  28. data/lib/concurrent/atomic/cyclic_barrier.rb +106 -0
  29. data/lib/concurrent/atomic/event.rb +98 -0
  30. data/lib/concurrent/atomic/thread_local_var.rb +117 -0
  31. data/lib/concurrent/atomic_reference/concurrent_update_error.rb +7 -0
  32. data/lib/concurrent/atomic_reference/delegated_update.rb +28 -0
  33. data/lib/concurrent/atomic_reference/direct_update.rb +28 -0
  34. data/lib/concurrent/atomic_reference/jruby.rb +8 -0
  35. data/lib/concurrent/atomic_reference/mutex_atomic.rb +47 -0
  36. data/lib/concurrent/atomic_reference/numeric_cas_wrapper.rb +24 -0
  37. data/lib/concurrent/atomic_reference/rbx.rb +16 -0
  38. data/lib/concurrent/atomic_reference/ruby.rb +16 -0
  39. data/lib/concurrent/atomics.rb +10 -0
  40. data/lib/concurrent/channel/buffered_channel.rb +85 -0
  41. data/lib/concurrent/channel/channel.rb +41 -0
  42. data/lib/concurrent/channel/unbuffered_channel.rb +34 -0
  43. data/lib/concurrent/channel/waitable_list.rb +40 -0
  44. data/lib/concurrent/channels.rb +5 -0
  45. data/lib/concurrent/collection/blocking_ring_buffer.rb +71 -0
  46. data/lib/concurrent/collection/priority_queue.rb +305 -0
  47. data/lib/concurrent/collection/ring_buffer.rb +59 -0
  48. data/lib/concurrent/collections.rb +3 -0
  49. data/lib/concurrent/configuration.rb +158 -0
  50. data/lib/concurrent/dataflow.rb +91 -0
  51. data/lib/concurrent/delay.rb +112 -0
  52. data/lib/concurrent/dereferenceable.rb +101 -0
  53. data/lib/concurrent/errors.rb +30 -0
  54. data/lib/concurrent/exchanger.rb +34 -0
  55. data/lib/concurrent/executor/cached_thread_pool.rb +44 -0
  56. data/lib/concurrent/executor/executor.rb +229 -0
  57. data/lib/concurrent/executor/fixed_thread_pool.rb +33 -0
  58. data/lib/concurrent/executor/immediate_executor.rb +16 -0
  59. data/lib/concurrent/executor/java_cached_thread_pool.rb +31 -0
  60. data/lib/concurrent/executor/java_fixed_thread_pool.rb +33 -0
  61. data/lib/concurrent/executor/java_single_thread_executor.rb +21 -0
  62. data/lib/concurrent/executor/java_thread_pool_executor.rb +187 -0
  63. data/lib/concurrent/executor/per_thread_executor.rb +24 -0
  64. data/lib/concurrent/executor/ruby_cached_thread_pool.rb +29 -0
  65. data/lib/concurrent/executor/ruby_fixed_thread_pool.rb +32 -0
  66. data/lib/concurrent/executor/ruby_single_thread_executor.rb +73 -0
  67. data/lib/concurrent/executor/ruby_thread_pool_executor.rb +286 -0
  68. data/lib/concurrent/executor/ruby_thread_pool_worker.rb +72 -0
  69. data/lib/concurrent/executor/safe_task_executor.rb +35 -0
  70. data/lib/concurrent/executor/serialized_execution.rb +90 -0
  71. data/lib/concurrent/executor/single_thread_executor.rb +35 -0
  72. data/lib/concurrent/executor/thread_pool_executor.rb +68 -0
  73. data/lib/concurrent/executor/timer_set.rb +143 -0
  74. data/lib/concurrent/executors.rb +9 -0
  75. data/lib/concurrent/future.rb +124 -0
  76. data/lib/concurrent/ivar.rb +111 -0
  77. data/lib/concurrent/logging.rb +17 -0
  78. data/lib/concurrent/mvar.rb +200 -0
  79. data/lib/concurrent/obligation.rb +171 -0
  80. data/lib/concurrent/observable.rb +40 -0
  81. data/lib/concurrent/options_parser.rb +46 -0
  82. data/lib/concurrent/promise.rb +169 -0
  83. data/lib/concurrent/scheduled_task.rb +78 -0
  84. data/lib/concurrent/supervisor.rb +343 -0
  85. data/lib/concurrent/timer_task.rb +341 -0
  86. data/lib/concurrent/tvar.rb +252 -0
  87. data/lib/concurrent/utilities.rb +3 -0
  88. data/lib/concurrent/utility/processor_count.rb +150 -0
  89. data/lib/concurrent/utility/timeout.rb +35 -0
  90. data/lib/concurrent/utility/timer.rb +21 -0
  91. data/lib/concurrent/version.rb +3 -0
  92. data/lib/concurrent_ruby.rb +1 -0
  93. data/lib/concurrent_ruby_ext.so +0 -0
  94. data/lib/extension_helper.rb +9 -0
  95. metadata +141 -0
@@ -0,0 +1,33 @@
1
+ require 'concurrent/executor/ruby_fixed_thread_pool'
2
+
3
+ module Concurrent
4
+
5
+ if RUBY_PLATFORM == 'java'
6
+ require 'concurrent/executor/java_fixed_thread_pool'
7
+ # @!macro [attach] fixed_thread_pool
8
+ #
9
+ # A thread pool with a set number of threads. The number of threads in the pool
10
+ # is set on construction and remains constant. When all threads are busy new
11
+ # tasks `#post` to the thread pool are enqueued until a thread becomes available.
12
+ # Should a thread crash for any reason the thread will immediately be removed
13
+ # from the pool and replaced.
14
+ #
15
+ # The API and behavior of this class are based on Java's `FixedThreadPool`
16
+ #
17
+ # @note When running on the JVM (JRuby) this class will inherit from `JavaFixedThreadPool`.
18
+ # On all other platforms it will inherit from `RubyFixedThreadPool`.
19
+ #
20
+ # @see Concurrent::RubyFixedThreadPool
21
+ # @see Concurrent::JavaFixedThreadPool
22
+ #
23
+ # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
24
+ # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
25
+ # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
26
+ class FixedThreadPool < JavaFixedThreadPool
27
+ end
28
+ else
29
+ # @!macro fixed_thread_pool
30
+ class FixedThreadPool < RubyFixedThreadPool
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ module Concurrent
2
+ class ImmediateExecutor
3
+ include Executor
4
+
5
+ def post(*args, &task)
6
+ raise ArgumentError.new('no block given') unless block_given?
7
+ task.call(*args)
8
+ true
9
+ end
10
+
11
+ def <<(task)
12
+ post(&task)
13
+ self
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ if RUBY_PLATFORM == 'java'
2
+
3
+ require 'concurrent/executor/java_thread_pool_executor'
4
+
5
+ module Concurrent
6
+
7
+ # @!macro cached_thread_pool
8
+ class JavaCachedThreadPool < JavaThreadPoolExecutor
9
+
10
+ # Create a new thread pool.
11
+ #
12
+ # @param [Hash] opts the options defining pool behavior.
13
+ # @option opts [Symbol] :overflow_policy (`:abort`) the overflow policy
14
+ #
15
+ # @raise [ArgumentError] if `overflow_policy` is not a known policy
16
+ #
17
+ # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool--
18
+ def initialize(opts = {})
19
+ @overflow_policy = opts.fetch(:overflow_policy, :abort)
20
+ @max_queue = 0
21
+
22
+ raise ArgumentError.new("#{@overflow_policy} is not a valid overflow policy") unless OVERFLOW_POLICIES.keys.include?(@overflow_policy)
23
+
24
+ @executor = java.util.concurrent.Executors.newCachedThreadPool
25
+ @executor.setRejectedExecutionHandler(OVERFLOW_POLICIES[@overflow_policy].new)
26
+
27
+ set_shutdown_hook
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ if RUBY_PLATFORM == 'java'
2
+
3
+ require 'concurrent/executor/java_thread_pool_executor'
4
+
5
+ module Concurrent
6
+
7
+ # @!macro fixed_thread_pool
8
+ class JavaFixedThreadPool < JavaThreadPoolExecutor
9
+
10
+ # Create a new thread pool.
11
+ #
12
+ # @param [Hash] opts the options defining pool behavior.
13
+ # @option opts [Symbol] :overflow_policy (`:abort`) the overflow policy
14
+ #
15
+ # @raise [ArgumentError] if `num_threads` is less than or equal to zero
16
+ # @raise [ArgumentError] if `overflow_policy` is not a known policy
17
+ #
18
+ # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int-
19
+ def initialize(num_threads, opts = {})
20
+ @overflow_policy = opts.fetch(:overflow_policy, :abort)
21
+ @max_queue = 0
22
+
23
+ raise ArgumentError.new('number of threads must be greater than zero') if num_threads < 1
24
+ raise ArgumentError.new("#{@overflow_policy} is not a valid overflow policy") unless OVERFLOW_POLICIES.keys.include?(@overflow_policy)
25
+
26
+ @executor = java.util.concurrent.Executors.newFixedThreadPool(num_threads)
27
+ @executor.setRejectedExecutionHandler(OVERFLOW_POLICIES[@overflow_policy].new)
28
+
29
+ set_shutdown_hook
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ if RUBY_PLATFORM == 'java'
2
+ require_relative 'executor'
3
+
4
+ module Concurrent
5
+
6
+ # @!macro single_thread_executor
7
+ class JavaSingleThreadExecutor
8
+ include JavaExecutor
9
+
10
+ # Create a new thread pool.
11
+ #
12
+ # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
13
+ # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
14
+ # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
15
+ def initialize(opts = {})
16
+ @executor = java.util.concurrent.Executors.newSingleThreadExecutor
17
+ set_shutdown_hook
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,187 @@
1
+ if RUBY_PLATFORM == 'java'
2
+ require_relative 'executor'
3
+
4
+ module Concurrent
5
+
6
+ # @!macro thread_pool_executor
7
+ class JavaThreadPoolExecutor
8
+ include JavaExecutor
9
+
10
+ # Default maximum number of threads that will be created in the pool.
11
+ DEFAULT_MAX_POOL_SIZE = java.lang.Integer::MAX_VALUE # 2147483647
12
+
13
+ # Default minimum number of threads that will be retained in the pool.
14
+ DEFAULT_MIN_POOL_SIZE = 0
15
+
16
+ # Default maximum number of tasks that may be added to the task queue.
17
+ DEFAULT_MAX_QUEUE_SIZE = 0
18
+
19
+ # Default maximum number of seconds a thread in the pool may remain idle
20
+ # before being reclaimed.
21
+ DEFAULT_THREAD_IDLETIMEOUT = 60
22
+
23
+ # The set of possible overflow policies that may be set at thread pool creation.
24
+ OVERFLOW_POLICIES = {
25
+ abort: java.util.concurrent.ThreadPoolExecutor::AbortPolicy,
26
+ discard: java.util.concurrent.ThreadPoolExecutor::DiscardPolicy,
27
+ caller_runs: java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy
28
+ }.freeze
29
+
30
+ # The maximum number of threads that may be created in the pool.
31
+ attr_reader :max_length
32
+
33
+ # The maximum number of tasks that may be waiting in the work queue at any one time.
34
+ # When the queue size reaches `max_queue` subsequent tasks will be rejected in
35
+ # accordance with the configured `overflow_policy`.
36
+ attr_reader :max_queue
37
+
38
+ # The policy defining how rejected tasks (tasks received once the queue size reaches
39
+ # the configured `max_queue`) are handled. Must be one of the values specified in
40
+ # `OVERFLOW_POLICIES`.
41
+ attr_reader :overflow_policy
42
+
43
+ # Create a new thread pool.
44
+ #
45
+ # @param [Hash] opts the options which configure the thread pool
46
+ #
47
+ # @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum
48
+ # number of threads to be created
49
+ # @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) the minimum
50
+ # number of threads to be retained
51
+ # @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum
52
+ # number of seconds a thread may be idle before being reclaimed
53
+ # @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum
54
+ # number of tasks allowed in the work queue at any one time; a value of
55
+ # zero means the queue may grow without bounnd
56
+ # @option opts [Symbol] :overflow_policy (:abort) the policy for handling new
57
+ # tasks that are received when the queue size has reached `max_queue`
58
+ #
59
+ # @raise [ArgumentError] if `:max_threads` is less than one
60
+ # @raise [ArgumentError] if `:min_threads` is less than zero
61
+ # @raise [ArgumentError] if `:overflow_policy` is not one of the values specified
62
+ # in `OVERFLOW_POLICIES`
63
+ #
64
+ # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
65
+ def initialize(opts = {})
66
+ min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i
67
+ max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i
68
+ idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i
69
+ @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i
70
+ @overflow_policy = opts.fetch(:overflow_policy, :abort)
71
+
72
+ raise ArgumentError.new('max_threads must be greater than zero') if max_length <= 0
73
+ raise ArgumentError.new('min_threads cannot be less than zero') if min_length < 0
74
+ raise ArgumentError.new("#{@overflow_policy} is not a valid overflow policy") unless OVERFLOW_POLICIES.keys.include?(@overflow_policy)
75
+
76
+ if min_length == 0 && @max_queue == 0
77
+ queue = java.util.concurrent.SynchronousQueue.new
78
+ elsif @max_queue == 0
79
+ queue = java.util.concurrent.LinkedBlockingQueue.new
80
+ else
81
+ queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue)
82
+ end
83
+
84
+ @executor = java.util.concurrent.ThreadPoolExecutor.new(
85
+ min_length, max_length,
86
+ idletime, java.util.concurrent.TimeUnit::SECONDS,
87
+ queue, OVERFLOW_POLICIES[@overflow_policy].new)
88
+
89
+ set_shutdown_hook
90
+ end
91
+
92
+ def can_overflow?
93
+ @max_queue != 0
94
+ end
95
+
96
+ # The minimum number of threads that may be retained in the pool.
97
+ #
98
+ # @return [Integer] the min_length
99
+ def min_length
100
+ @executor.getCorePoolSize
101
+ end
102
+
103
+ # The maximum number of threads that may be created in the pool.
104
+ #
105
+ # @return [Integer] the max_length
106
+ def max_length
107
+ @executor.getMaximumPoolSize
108
+ end
109
+
110
+ # The number of threads currently in the pool.
111
+ #
112
+ # @return [Integer] the length
113
+ def length
114
+ @executor.getPoolSize
115
+ end
116
+ alias_method :current_length, :length
117
+
118
+ # The largest number of threads that have been created in the pool since construction.
119
+ #
120
+ # @return [Integer] the largest_length
121
+ def largest_length
122
+ @executor.getLargestPoolSize
123
+ end
124
+
125
+ # The number of tasks that have been scheduled for execution on the pool since construction.
126
+ #
127
+ # @return [Integer] the scheduled_task_count
128
+ def scheduled_task_count
129
+ @executor.getTaskCount
130
+ end
131
+
132
+ # The number of tasks that have been completed by the pool since construction.
133
+ #
134
+ # @return [Integer] the completed_task_count
135
+ def completed_task_count
136
+ @executor.getCompletedTaskCount
137
+ end
138
+
139
+ # The number of seconds that a thread may be idle before being reclaimed.
140
+ #
141
+ # @return [Integer] the idletime
142
+ def idletime
143
+ @executor.getKeepAliveTime(java.util.concurrent.TimeUnit::SECONDS)
144
+ end
145
+
146
+ # The number of tasks in the queue awaiting execution.
147
+ #
148
+ # @return [Integer] the queue_length
149
+ def queue_length
150
+ @executor.getQueue.size
151
+ end
152
+
153
+ # Number of tasks that may be enqueued before reaching `max_queue` and rejecting
154
+ # new tasks. A value of -1 indicates that the queue may grow without bound.
155
+ #
156
+ # @return [Integer] the remaining_capacity
157
+ def remaining_capacity
158
+ @max_queue == 0 ? -1 : @executor.getQueue.remainingCapacity
159
+ end
160
+
161
+ # This method is deprecated and will be removed soon.
162
+ # This method is supost to return the threads status, but Java API doesn't
163
+ # provide a way to get the thread status. So we return an empty Array instead.
164
+ def status
165
+ warn '[DEPRECATED] `status` is deprecated and will be removed soon.'
166
+ warn "Calls to `status` return an empty Array. Java ThreadPoolExecutor does not provide thread's status."
167
+ []
168
+ end
169
+
170
+ # Is the thread pool running?
171
+ #
172
+ # @return [Boolean] `true` when running, `false` when shutting down or shutdown
173
+ def running?
174
+ super && ! @executor.isTerminating
175
+ end
176
+
177
+ # Begin an orderly shutdown. Tasks already in the queue will be executed,
178
+ # but no new tasks will be accepted. Has no additional effect if the
179
+ # thread pool is not running.
180
+ def shutdown
181
+ super
182
+ @executor.getQueue.clear
183
+ nil
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,24 @@
1
+ module Concurrent
2
+
3
+ class PerThreadExecutor
4
+ include Executor
5
+
6
+ def self.post(*args)
7
+ raise ArgumentError.new('no block given') unless block_given?
8
+ Thread.new(*args) do
9
+ Thread.current.abort_on_exception = false
10
+ yield(*args)
11
+ end
12
+ return true
13
+ end
14
+
15
+ def post(*args, &task)
16
+ return PerThreadExecutor.post(*args, &task)
17
+ end
18
+
19
+ def <<(task)
20
+ PerThreadExecutor.post(&task)
21
+ return self
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ require 'concurrent/executor/ruby_thread_pool_executor'
2
+
3
+ module Concurrent
4
+
5
+ # @!macro cached_thread_pool
6
+ class RubyCachedThreadPool < RubyThreadPoolExecutor
7
+
8
+ # Create a new thread pool.
9
+ #
10
+ # @param [Hash] opts the options defining pool behavior.
11
+ # number of seconds a thread may be idle before it is reclaimed
12
+ #
13
+ # @raise [ArgumentError] if `overflow_policy` is not a known policy
14
+ def initialize(opts = {})
15
+ overflow_policy = opts.fetch(:overflow_policy, :abort)
16
+
17
+ raise ArgumentError.new("#{overflow_policy} is not a valid overflow policy") unless OVERFLOW_POLICIES.include?(overflow_policy)
18
+
19
+ opts = opts.merge(
20
+ min_threads: 0,
21
+ max_threads: DEFAULT_MAX_POOL_SIZE,
22
+ num_threads: overflow_policy,
23
+ max_queue: DEFAULT_MAX_QUEUE_SIZE,
24
+ idletime: DEFAULT_THREAD_IDLETIMEOUT
25
+ )
26
+ super(opts)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ require 'concurrent/executor/ruby_thread_pool_executor'
2
+
3
+ module Concurrent
4
+
5
+ # @!macro fixed_thread_pool
6
+ class RubyFixedThreadPool < RubyThreadPoolExecutor
7
+
8
+ # Create a new thread pool.
9
+ #
10
+ # @param [Integer] num_threads the number of threads to allocate
11
+ # @param [Hash] opts the options defining pool behavior.
12
+ # @option opts [Symbol] :overflow_policy (`:abort`) the overflow policy
13
+ #
14
+ # @raise [ArgumentError] if `num_threads` is less than or equal to zero
15
+ # @raise [ArgumentError] if `overflow_policy` is not a known policy
16
+ def initialize(num_threads, opts = {})
17
+ overflow_policy = opts.fetch(:overflow_policy, :abort)
18
+
19
+ raise ArgumentError.new('number of threads must be greater than zero') if num_threads < 1
20
+ raise ArgumentError.new("#{overflow_policy} is not a valid overflow policy") unless OVERFLOW_POLICIES.include?(overflow_policy)
21
+
22
+ opts = opts.merge(
23
+ min_threads: num_threads,
24
+ max_threads: num_threads,
25
+ num_threads: overflow_policy,
26
+ max_queue: DEFAULT_MAX_QUEUE_SIZE,
27
+ idletime: 0
28
+ )
29
+ super(opts)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,73 @@
1
+ require_relative 'executor'
2
+
3
+ module Concurrent
4
+
5
+ # @!macro single_thread_executor
6
+ class RubySingleThreadExecutor
7
+ include RubyExecutor
8
+
9
+ # Create a new thread pool.
10
+ #
11
+ # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
12
+ # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
13
+ # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
14
+ def initialize(opts = {})
15
+ @queue = Queue.new
16
+ @thread = nil
17
+ init_executor
18
+ end
19
+
20
+ protected
21
+
22
+ # @!visibility private
23
+ def execute(*args, &task)
24
+ supervise
25
+ @queue << [args, task]
26
+ end
27
+
28
+ # @!visibility private
29
+ def shutdown_execution
30
+ @queue << :stop
31
+ stopped_event.set unless alive?
32
+ end
33
+
34
+ # @!visibility private
35
+ def kill_execution
36
+ @queue.clear
37
+ @thread.kill if alive?
38
+ end
39
+
40
+ # @!visibility private
41
+ def alive?
42
+ @thread && @thread.alive?
43
+ end
44
+
45
+ # @!visibility private
46
+ def supervise
47
+ @thread = new_worker_thread unless alive?
48
+ end
49
+
50
+ # @!visibility private
51
+ def new_worker_thread
52
+ Thread.new do
53
+ Thread.current.abort_on_exception = false
54
+ work
55
+ end
56
+ end
57
+
58
+ # @!visibility private
59
+ def work
60
+ loop do
61
+ task = @queue.pop
62
+ break if task == :stop
63
+ begin
64
+ task.last.call(*task.first)
65
+ rescue => ex
66
+ # let it fail
67
+ log DEBUG, ex
68
+ end
69
+ end
70
+ stopped_event.set
71
+ end
72
+ end
73
+ end