Class: Concurrent::SingleThreadExecutor

Inherits:
SingleThreadExecutorImplementation
  • Object
show all
Defined in:
lib/concurrent/executor/single_thread_executor.rb

Overview

Note:

Failure to properly shutdown a thread pool can lead to unpredictable results. Please read *Shutting Down Thread Pools* for more information.

A thread pool with a set number of threads. The number of threads in the pool is set on construction and remains constant. When all threads are busy new tasks #post to the thread pool are enqueued until a thread becomes available. Should a thread crash for any reason the thread will immediately be removed from the pool and replaced.

The API and behavior of this class are based on Java’s SingleThreadExecutor

**Thread Pool Options**

Thread pools support several configuration options:

  • idletime: The number of seconds that a thread may be idle before being reclaimed.

  • max_queue: The maximum number of tasks that may be waiting in the work queue at any one time. When the queue size reaches max_queue subsequent tasks will be rejected in accordance with the configured fallback_policy.

  • auto_terminate: When true (default) an at_exit handler will be registered which will stop the thread pool when the application exits. See below for more information on shutting down thread pools.

  • fallback_policy: The policy defining how rejected tasks are handled.

Three fallback policies are supported:

  • :abort: Raise a RejectedExecutionError exception and discard the task.

  • :discard: Discard the task and return false.

  • :caller_runs: Execute the task on the calling thread.

**Shutting Down Thread Pools**

Killing a thread pool while tasks are still being processed, either by calling the #kill method or at application exit, will have unpredictable results. There is no way for the thread pool to know what resources are being used by the in-progress tasks. When those tasks are killed the impact on those resources cannot be predicted. The best practice is to explicitly shutdown all thread pools using the provided methods:

  • Call #shutdown to initiate an orderly termination of all in-progress tasks

  • Call #wait_for_termination with an appropriate timeout interval an allow the orderly shutdown to complete

  • Call #kill *only when* the thread pool fails to shutdown in the allotted time

On some runtime platforms (most notably the JVM) the application will not exit until all thread pools have been shutdown. To prevent applications from “hanging” on exit all thread pools include an at_exit handler that will stop the thread pool when the application exists. This handler uses a brute force method to stop the pool and makes no guarantees regarding resources being used by any tasks still running. Registration of this at_exit handler can be prevented by setting the thread pool’s constructor :auto_terminate option to false when the thread pool is created. All thread pools support this option.

“‘ruby pool1 = Concurrent::FixedThreadPool.new(5) # an at_exit handler will be registered pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # prevent at_exit handler registration “`

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fallback_policyObject (readonly)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

Instance Method Details

#<<(task) ⇒ self

Submit a task to the executor for asynchronous processing.

Parameters:

  • task (Proc)

    the asynchronous task to perform

Returns:

  • (self)

    returns itself



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#auto_terminate=(value) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#auto_terminate?Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#can_overflow?Boolean

Does the task queue have a maximum size?

Returns:

  • (Boolean)

    True if the task queue has a maximum size else false.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#killObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#post(*args) { ... } ⇒ Boolean

Submit a task to the executor for asynchronous processing.

Parameters:

  • args (Array)

    zero or more arguments to be passed to the task

Yields:

  • the asynchronous task to perform

Returns:

  • (Boolean)

    true if the task is queued, false if the executor is not running

Raises:

  • (ArgumentError)

    if no task is given



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#running?Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#serialized?Boolean

Does this executor guarantee serialization of its operations?

Returns:

  • (Boolean)

    True if the executor guarantees that all operations will be post in the order they are received and no two operations may occur simultaneously. Else false.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#shutdownObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#shutdown?Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#shuttingdown?Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end

#wait_for_termination(timeout = nil) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/concurrent/executor/single_thread_executor.rb', line 29

class SingleThreadExecutor < SingleThreadExecutorImplementation

  # @!macro [new] single_thread_executor_method_initialize
  #
  #   Create a new thread pool.
  #
  #   @option opts [Symbol] :fallback_policy (:discard) the policy for
  #     handling new tasks that are received when the queue size has
  #     reached `max_queue` or after the executor has shut down
  #
  #   @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
  #   @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
  #   @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

  # @!method initialize(opts = {})
  #   @!macro single_thread_executor_method_initialize
end