Skip to content

Commit 8ccb214

Browse files
authored
Merge pull request #841 from fzakaria/remove-at-exit
Remove AtExit code
2 parents a4d7a75 + 2c13ac6 commit 8ccb214

19 files changed

+80
-204
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## Current
22

3+
concurrent-ruby:
4+
5+
* Concurrent.disable_at_exit_handlers! is no longer needed and was deprecated.
6+
* AbstractExecutorService#auto_terminate= was deprecated and has no effect.
7+
Set :auto_terminate option instead when executor is initialized.
8+
39
## Release v1.1.6.pre1, edge v0.6.0.pre1 (26 Jan 2020)
410

511
concurrent-ruby:

lib/concurrent-ruby-edge/concurrent/channel.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Channel
1515
include Enumerable
1616

1717
# NOTE: Move to global IO pool once stable
18-
GOROUTINES = Concurrent::CachedThreadPool.new(auto_terminate: true)
18+
GOROUTINES = Concurrent::CachedThreadPool.new
1919
private_constant :GOROUTINES
2020

2121
BUFFER_TYPES = {

lib/concurrent-ruby/concurrent/configuration.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
require 'concurrent/errors'
44
require 'concurrent/atomic/atomic_reference'
55
require 'concurrent/concern/logging'
6+
require 'concurrent/concern/deprecation'
67
require 'concurrent/executor/immediate_executor'
78
require 'concurrent/executor/cached_thread_pool'
8-
require 'concurrent/utility/at_exit'
99
require 'concurrent/utility/processor_counter'
1010

1111
module Concurrent
1212
extend Concern::Logging
13+
extend Concern::Deprecation
1314

1415
autoload :Options, 'concurrent/options'
1516
autoload :TimerSet, 'concurrent/executor/timer_set'
@@ -97,15 +98,15 @@ def self.global_logger=(value)
9798
end
9899

99100
# @!visibility private
100-
GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor(auto_terminate: true) }
101+
GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor }
101102
private_constant :GLOBAL_FAST_EXECUTOR
102103

103104
# @!visibility private
104-
GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor(auto_terminate: true) }
105+
GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor }
105106
private_constant :GLOBAL_IO_EXECUTOR
106107

107108
# @!visibility private
108-
GLOBAL_TIMER_SET = Delay.new { TimerSet.new(auto_terminate: true) }
109+
GLOBAL_TIMER_SET = Delay.new { TimerSet.new }
109110
private_constant :GLOBAL_TIMER_SET
110111

111112
# @!visibility private
@@ -125,9 +126,10 @@ def self.global_logger=(value)
125126
# @note This method should *never* be called
126127
# from within a gem. It should *only* be used from within the main
127128
# application and even then it should be used only when necessary.
129+
# @deprecated Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841.
128130
#
129131
def self.disable_at_exit_handlers!
130-
AT_EXIT.enabled = false
132+
deprecated "Method #disable_at_exit_handlers! has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841."
131133
end
132134

133135
# Global thread pool optimized for short, fast *operations*.

lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
require 'concurrent/errors'
2+
require 'concurrent/concern/deprecation'
23
require 'concurrent/executor/executor_service'
34
require 'concurrent/synchronization'
4-
require 'concurrent/utility/at_exit'
55

66
module Concurrent
77

88
# @!macro abstract_executor_service_public_api
99
# @!visibility private
1010
class AbstractExecutorService < Synchronization::LockableObject
1111
include ExecutorService
12+
include Concern::Deprecation
1213

1314
# The set of possible fallback policies that may be set at thread pool creation.
1415
FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze
@@ -22,8 +23,9 @@ class AbstractExecutorService < Synchronization::LockableObject
2223
def initialize(opts = {}, &block)
2324
super(&nil)
2425
synchronize do
25-
ns_initialize(opts, &block)
26+
@auto_terminate = opts.fetch(:auto_terminate, true)
2627
@name = opts.fetch(:name) if opts.key?(:name)
28+
ns_initialize(opts, &block)
2729
end
2830
end
2931

@@ -63,12 +65,12 @@ def shutdown?
6365

6466
# @!macro executor_service_method_auto_terminate_question
6567
def auto_terminate?
66-
synchronize { ns_auto_terminate? }
68+
synchronize { @auto_terminate }
6769
end
6870

6971
# @!macro executor_service_method_auto_terminate_setter
7072
def auto_terminate=(value)
71-
synchronize { self.ns_auto_terminate = value }
73+
deprecated "Method #auto_terminate= has no effect. Set :auto_terminate option when executor is initialized."
7274
end
7375

7476
private
@@ -119,25 +121,8 @@ def ns_kill_execution
119121
end
120122

121123
def ns_auto_terminate?
122-
!!@auto_terminate
124+
@auto_terminate
123125
end
124126

125-
def ns_auto_terminate=(value)
126-
case value
127-
when true
128-
AT_EXIT.add(self) { terminate_at_exit }
129-
@auto_terminate = true
130-
when false
131-
AT_EXIT.delete(self)
132-
@auto_terminate = false
133-
else
134-
raise ArgumentError
135-
end
136-
end
137-
138-
def terminate_at_exit
139-
kill # TODO be gentle first
140-
wait_for_termination(10)
141-
end
142127
end
143128
end

lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ def initialize(opts = {})
5151
def ns_initialize(opts)
5252
super(opts)
5353
if Concurrent.on_jruby?
54-
self.auto_terminate = opts.fetch(:auto_terminate, true)
5554
@max_queue = 0
5655
@executor = java.util.concurrent.Executors.newCachedThreadPool(
57-
DaemonThreadFactory.new(self.auto_terminate?))
56+
DaemonThreadFactory.new(ns_auto_terminate?))
5857
@executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new)
5958
@executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS)
6059
end

lib/concurrent-ruby/concurrent/executor/executor_service.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ module Concurrent
111111

112112
# @!macro executor_service_method_auto_terminate_setter
113113
#
114-
# Set the auto-terminate behavior for this executor.
115114
#
115+
# Set the auto-terminate behavior for this executor.
116+
# @deprecated Has no effect
116117
# @param [Boolean] value The new auto-terminate value to set for this executor.
117-
#
118118
# @return [Boolean] `true` when auto-termination is enabled else `false`.
119119

120120
###################################################################

lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ module Concurrent
121121
# * `max_queue`: The maximum number of tasks that may be waiting in the work queue at
122122
# any one time. When the queue size reaches `max_queue` and no new threads can be created,
123123
# subsequent tasks will be rejected in accordance with the configured `fallback_policy`.
124-
# * `auto_terminate`: When true (default) an `at_exit` handler will be registered which
125-
# will stop the thread pool when the application exits. See below for more information
126-
# on shutting down thread pools.
124+
# * `auto_terminate`: When true (default), the threads started will be marked as daemon.
127125
# * `fallback_policy`: The policy defining how rejected tasks are handled.
128126
#
129127
# Three fallback policies are supported:
@@ -148,16 +146,12 @@ module Concurrent
148146
#
149147
# On some runtime platforms (most notably the JVM) the application will not
150148
# exit until all thread pools have been shutdown. To prevent applications from
151-
# "hanging" on exit all thread pools include an `at_exit` handler that will
152-
# stop the thread pool when the application exits. This handler uses a brute
153-
# force method to stop the pool and makes no guarantees regarding resources being
154-
# used by any tasks still running. Registration of this `at_exit` handler can be
155-
# prevented by setting the thread pool's constructor `:auto_terminate` option to
156-
# `false` when the thread pool is created. All thread pools support this option.
149+
# "hanging" on exit, all threads can be marked as daemon according to the
150+
# `:auto_terminate` option.
157151
#
158152
# ```ruby
159-
# pool1 = Concurrent::FixedThreadPool.new(5) # an `at_exit` handler will be registered
160-
# pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # prevent `at_exit` handler registration
153+
# pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon
154+
# pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon
161155
# ```
162156
#
163157
# @note Failure to properly shutdown a thread pool can lead to unpredictable results.
@@ -166,7 +160,7 @@ module Concurrent
166160
# @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools
167161
# @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class
168162
# @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface
169-
# @see http://ruby-doc.org//core-2.2.0/Kernel.html#method-i-at_exit Kernel#at_exit
163+
# @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean-
170164

171165

172166

lib/concurrent-ruby/concurrent/executor/java_executor_service.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@ def wait_for_termination(timeout = nil)
3838

3939
def shutdown
4040
synchronize do
41-
self.ns_auto_terminate = false
4241
@executor.shutdown
4342
nil
4443
end
4544
end
4645

4746
def kill
4847
synchronize do
49-
self.ns_auto_terminate = false
5048
@executor.shutdownNow
5149
nil
5250
end
@@ -83,5 +81,23 @@ def run
8381
end
8482
private_constant :Job
8583
end
84+
85+
class DaemonThreadFactory
86+
# hide include from YARD
87+
send :include, java.util.concurrent.ThreadFactory
88+
89+
def initialize(daemonize = true)
90+
@daemonize = daemonize
91+
end
92+
93+
def newThread(runnable)
94+
thread = java.util.concurrent.Executors.defaultThreadFactory().newThread(runnable)
95+
thread.setDaemon(@daemonize)
96+
return thread
97+
end
98+
end
99+
100+
private_constant :DaemonThreadFactory
101+
86102
end
87103
end

lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ def initialize(opts = {})
1717
end
1818

1919
private
20-
20+
2121
def ns_initialize(opts)
22-
@executor = java.util.concurrent.Executors.newSingleThreadExecutor
22+
@executor = java.util.concurrent.Executors.newSingleThreadExecutor(
23+
DaemonThreadFactory.new(ns_auto_terminate?)
24+
)
2325
@fallback_policy = opts.fetch(:fallback_policy, :discard)
2426
raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.keys.include?(@fallback_policy)
25-
self.auto_terminate = opts.fetch(:auto_terminate, true)
2627
end
2728
end
2829
end

lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -108,35 +108,17 @@ def ns_initialize(opts)
108108
queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue)
109109
end
110110

111-
self.auto_terminate = opts.fetch(:auto_terminate, true)
112-
113111
@executor = java.util.concurrent.ThreadPoolExecutor.new(
114112
min_length,
115113
max_length,
116114
idletime,
117115
java.util.concurrent.TimeUnit::SECONDS,
118116
queue,
119-
DaemonThreadFactory.new(self.auto_terminate?),
117+
DaemonThreadFactory.new(ns_auto_terminate?),
120118
FALLBACK_POLICY_CLASSES[@fallback_policy].new)
121119

122120
end
123121
end
124122

125-
class DaemonThreadFactory
126-
# hide include from YARD
127-
send :include, java.util.concurrent.ThreadFactory
128-
129-
def initialize(daemonize = true)
130-
@daemonize = daemonize
131-
end
132-
133-
def newThread(runnable)
134-
thread = java.util.concurrent.Executors.defaultThreadFactory().newThread(runnable)
135-
thread.setDaemon(@daemonize)
136-
return thread
137-
end
138-
end
139-
140-
private_constant :DaemonThreadFactory
141123
end
142124
end

0 commit comments

Comments
 (0)