@@ -16,35 +16,20 @@ module Concurrent
16
16
private_constant :GLOBAL_LOGGER
17
17
18
18
# @!visibility private
19
- AUTO_TERMINATE_GLOBAL_EXECUTORS = AtomicBoolean . new ( true )
20
- private_constant :AUTO_TERMINATE_GLOBAL_EXECUTORS
21
-
22
- # @!visibility private
23
- AUTO_TERMINATE_ALL_EXECUTORS = AtomicBoolean . new ( true )
24
- private_constant :AUTO_TERMINATE_ALL_EXECUTORS
25
-
26
- # @!visibility private
27
- GLOBAL_FAST_EXECUTOR = Delay . new do
28
- Concurrent . new_fast_executor (
29
- stop_on_exit : AUTO_TERMINATE_GLOBAL_EXECUTORS . value )
30
- end
19
+ GLOBAL_FAST_EXECUTOR = Delay . new { Concurrent . new_fast_executor ( auto_terminate : true ) }
31
20
private_constant :GLOBAL_FAST_EXECUTOR
32
21
33
22
# @!visibility private
34
- GLOBAL_IO_EXECUTOR = Delay . new do
35
- Concurrent . new_io_executor (
36
- stop_on_exit : AUTO_TERMINATE_GLOBAL_EXECUTORS . value )
37
- end
23
+ GLOBAL_IO_EXECUTOR = Delay . new { Concurrent . new_io_executor ( auto_terminate : true ) }
38
24
private_constant :GLOBAL_IO_EXECUTOR
39
25
40
26
# @!visibility private
41
- GLOBAL_TIMER_SET = Delay . new do
42
- TimerSet . new ( stop_on_exit : AUTO_TERMINATE_GLOBAL_EXECUTORS . value )
43
- end
27
+ GLOBAL_TIMER_SET = Delay . new { TimerSet . new ( auto_terminate : true ) }
44
28
private_constant :GLOBAL_TIMER_SET
45
29
46
30
# @!visibility private
47
31
GLOBAL_IMMEDIATE_EXECUTOR = ImmediateExecutor . new
32
+ private_constant :GLOBAL_IMMEDIATE_EXECUTOR
48
33
49
34
def self . global_logger
50
35
GLOBAL_LOGGER . value
@@ -54,87 +39,34 @@ def self.global_logger=(value)
54
39
GLOBAL_LOGGER . value = value
55
40
end
56
41
57
- # Defines if global executors should be auto-terminated with an
58
- # `at_exit` callback. When set to `false` it will be the application
59
- # programmer's responsibility to ensure that the global thread pools
60
- # are shutdown properly prior to application exit.
61
- #
62
- # @note Only change this option if you know what you are doing!
63
- # When this is set to true (the default) then `at_exit` handlers
64
- # will be registered automatically for the *global* thread pools
65
- # to ensure that they are shutdown when the application ends. When
66
- # changed to false, the `at_exit` handlers will be circumvented
67
- # for all *global* thread pools. This method should *never* be called
68
- # from within a gem. It should *only* be used from within the main
69
- # application and even then it should be used only when necessary.
70
- #
71
- def self . disable_auto_termination_of_global_executors!
72
- AUTO_TERMINATE_GLOBAL_EXECUTORS . make_false
73
- end
74
-
75
- # Defines if global executors should be auto-terminated with an
76
- # `at_exit` callback. When set to `false` it will be the application
77
- # programmer's responsibility to ensure that the global thread pools
78
- # are shutdown properly prior to application exit.
42
+ # Disables pool auto-termination which is called on `at_exit` callback.
43
+ # When disabled it will be the application
44
+ # programmer's responsibility to ensure that the thread pools
45
+ # are shutdown properly prior to application exit
46
+ # by calling {.terminate_pools!} method.
79
47
#
80
- # @note Only change this option if you know what you are doing!
81
- # When this is set to true (the default) then `at_exit` handlers
82
- # will be registered automatically for the *global* thread pools
83
- # to ensure that they are shutdown when the application ends. When
84
- # changed to false, the `at_exit` handlers will be circumvented
85
- # for all *global* thread pools. This method should *never* be called
48
+ # @note this option should be needed only because of `at_exit` ordering
49
+ # issues which may arise when running some of the testing frameworks.
50
+ # E.g. Minitest's test-suite runs itself in `at_exit` callback which
51
+ # executes after the pools are already terminated. Then auto termination
52
+ # needs to be disabled and called manually after test-suite ends.
53
+ # @note This method should *never* be called
86
54
# from within a gem. It should *only* be used from within the main
87
55
# application and even then it should be used only when necessary.
88
- #
89
- # @return [Boolean] true when global thread pools will auto-terminate on
90
- # application exit using an `at_exit` handler; false when no auto-termination
91
- # will occur.
92
- def self . auto_terminate_global_executors?
93
- AUTO_TERMINATE_GLOBAL_EXECUTORS . value
56
+ def self . disable_executor_auto_termination!
57
+ Executor ::AT_EXIT_AUTO_TERMINATION . enabled = false
94
58
end
95
59
96
- # Defines if *ALL* executors should be auto-terminated with an
97
- # `at_exit` callback. When set to `false` it will be the application
98
- # programmer's responsibility to ensure that *all* thread pools,
99
- # including the global thread pools, are shutdown properly prior to
100
- # application exit.
101
- #
102
- # @note Only change this option if you know what you are doing!
103
- # When this is set to true (the default) then `at_exit` handlers
104
- # will be registered automatically for *all* thread pools to
105
- # ensure that they are shutdown when the application ends. When
106
- # changed to false, the `at_exit` handlers will be circumvented
107
- # for *all* Concurrent Ruby thread pools running within the
108
- # application. Even those created within other gems used by the
109
- # application. This method should *never* be called from within a
110
- # gem. It should *only* be used from within the main application.
111
- # And even then it should be used only when necessary.
112
- def self . disable_auto_termination_of_all_executors!
113
- AUTO_TERMINATE_ALL_EXECUTORS . make_false
60
+ # @return [true,false]
61
+ # @see .disable_executor_auto_termination!
62
+ def self . disable_executor_auto_termination?
63
+ Executor ::AT_EXIT_AUTO_TERMINATION . enabled?
114
64
end
115
65
116
- # Defines if *ALL* executors should be auto-terminated with an
117
- # `at_exit` callback. When set to `false` it will be the application
118
- # programmer's responsibility to ensure that *all* thread pools,
119
- # including the global thread pools, are shutdown properly prior to
120
- # application exit.
121
- #
122
- # @note Only change this option if you know what you are doing!
123
- # When this is set to true (the default) then `at_exit` handlers
124
- # will be registered automatically for *all* thread pools to
125
- # ensure that they are shutdown when the application ends. When
126
- # changed to false, the `at_exit` handlers will be circumvented
127
- # for *all* Concurrent Ruby thread pools running within the
128
- # application. Even those created within other gems used by the
129
- # application. This method should *never* be called from within a
130
- # gem. It should *only* be used from within the main application.
131
- # And even then it should be used only when necessary.
132
- #
133
- # @return [Boolean] true when *all* thread pools will auto-terminate on
134
- # application exit using an `at_exit` handler; false when no auto-termination
135
- # will occur.
136
- def self . auto_terminate_all_executors?
137
- AUTO_TERMINATE_ALL_EXECUTORS . value
66
+ # terminates all pools and blocks until they are terminated
67
+ # @see .disable_executor_auto_termination!
68
+ def self . terminate_pools!
69
+ Executor ::AT_EXIT_AUTO_TERMINATION . terminate
138
70
end
139
71
140
72
# Global thread pool optimized for short, fast *operations*.
@@ -151,6 +83,10 @@ def self.global_io_executor
151
83
GLOBAL_IO_EXECUTOR . value
152
84
end
153
85
86
+ def self . global_immediate_executor
87
+ GLOBAL_IMMEDIATE_EXECUTOR
88
+ end
89
+
154
90
# Global thread pool user for global *timers*.
155
91
#
156
92
# @return [Concurrent::TimerSet] the thread pool
@@ -160,44 +96,25 @@ def self.global_timer_set
160
96
GLOBAL_TIMER_SET . value
161
97
end
162
98
163
- def self . shutdown_global_executors
164
- global_fast_executor . shutdown
165
- global_io_executor . shutdown
166
- global_timer_set . shutdown
167
- end
168
-
169
- def self . kill_global_executors
170
- global_fast_executor . kill
171
- global_io_executor . kill
172
- global_timer_set . kill
173
- end
174
-
175
- def self . wait_for_global_executors_termination ( timeout = nil )
176
- latch = CountDownLatch . new ( 3 )
177
- [ global_fast_executor , global_io_executor , global_timer_set ] . each do |executor |
178
- Thread . new { executor . wait_for_termination ( timeout ) ; latch . count_down }
179
- end
180
- latch . wait ( timeout )
181
- end
182
-
183
99
def self . new_fast_executor ( opts = { } )
184
100
FixedThreadPool . new (
185
- [ 2 , Concurrent . processor_count ] . max ,
186
- stop_on_exit : opts . fetch ( :stop_on_exit , true ) ,
187
- idletime : 60 , # 1 minute
188
- max_queue : 0 , # unlimited
189
- fallback_policy : :caller_runs # shouldn't matter -- 0 max queue
101
+ [ 2 , Concurrent . processor_count ] . max ,
102
+ auto_terminate : opts . fetch ( :auto_terminate , true ) ,
103
+ idletime : 60 , # 1 minute
104
+ max_queue : 0 , # unlimited
105
+ fallback_policy : :caller_runs # shouldn't matter -- 0 max queue
190
106
)
191
107
end
192
108
193
109
def self . new_io_executor ( opts = { } )
194
110
ThreadPoolExecutor . new (
195
- min_threads : [ 2 , Concurrent . processor_count ] . max ,
196
- max_threads : ThreadPoolExecutor ::DEFAULT_MAX_POOL_SIZE ,
197
- stop_on_exit : opts . fetch ( :stop_on_exit , true ) ,
198
- idletime : 60 , # 1 minute
199
- max_queue : 0 , # unlimited
200
- fallback_policy : :caller_runs # shouldn't matter -- 0 max queue
111
+ min_threads : [ 2 , Concurrent . processor_count ] . max ,
112
+ max_threads : ThreadPoolExecutor ::DEFAULT_MAX_POOL_SIZE ,
113
+ # max_threads: 1000,
114
+ auto_terminate : opts . fetch ( :auto_terminate , true ) ,
115
+ idletime : 60 , # 1 minute
116
+ max_queue : 0 , # unlimited
117
+ fallback_policy : :caller_runs # shouldn't matter -- 0 max queue
201
118
)
202
119
end
203
120
@@ -256,15 +173,15 @@ def global_timer_set
256
173
def global_task_pool = ( executor )
257
174
warn '[DEPRECATED] Replacing global thread pools is deprecated. Use the :executor constructor option instead.'
258
175
GLOBAL_IO_EXECUTOR . reconfigure { executor } or
259
- raise ConfigurationError . new ( 'global task pool was already set' )
176
+ raise ConfigurationError . new ( 'global task pool was already set' )
260
177
end
261
178
262
179
# @deprecated Replacing global thread pools is deprecated.
263
180
# Use the :executor constructor option instead.
264
181
def global_operation_pool = ( executor )
265
182
warn '[DEPRECATED] Replacing global thread pools is deprecated. Use the :executor constructor option instead.'
266
183
GLOBAL_FAST_EXECUTOR . reconfigure { executor } or
267
- raise ConfigurationError . new ( 'global operation pool was already set' )
184
+ raise ConfigurationError . new ( 'global operation pool was already set' )
268
185
end
269
186
270
187
# @deprecated Use Concurrent.new_io_executor instead
@@ -293,11 +210,12 @@ def auto_terminate
293
210
end
294
211
295
212
# create the default configuration on load
296
- @configuration = Atomic . new ( Configuration . new )
213
+ CONFIGURATION = Atomic . new ( Configuration . new )
214
+ private_constant :CONFIGURATION
297
215
298
216
# @return [Configuration]
299
217
def self . configuration
300
- @configuration . value
218
+ CONFIGURATION . value
301
219
end
302
220
303
221
# Perform gem-level configuration.
0 commit comments