001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.spi;
018    
019    import java.util.List;
020    import java.util.concurrent.ExecutorService;
021    import java.util.concurrent.ScheduledExecutorService;
022    
023    import org.apache.camel.ShutdownableService;
024    import org.apache.camel.StaticService;
025    
026    /**
027     * Strategy to create thread pools.
028     * <p/>
029     * This manager is pluggable so you can plugin a custom provider, for example if you want to leverage
030     * the WorkManager for a JEE server.
031     * <p/>
032     * You may want to just implement a custom {@link ThreadPoolFactory} and rely on the
033     * {@link org.apache.camel.impl.DefaultExecutorServiceManager}, if that is sufficient. The {@link ThreadPoolFactory}
034     * is always used for creating the actual thread pools. You can implement a custom {@link ThreadPoolFactory}
035     * to leverage the WorkManager for a JEE server.
036     * <p/>
037     * The {@link ThreadPoolFactory} has pure JDK API, where as this {@link ExecutorServiceManager} has Camel API
038     * concepts such as {@link ThreadPoolProfile}. Therefore it may be easier to only implement a custom
039     * {@link ThreadPoolFactory}.
040     * <p/>
041     * This manager has fine grained methods for creating various thread pools, however custom strategies
042     * do not have to exactly create those kind of pools. Feel free to return a shared or different kind of pool.
043     * <p/>
044     * If you use the <tt>newXXX</tt> methods to create thread pools, then Camel will by default take care of
045     * shutting down those created pools when {@link org.apache.camel.CamelContext} is shutting down.
046     * <p/>
047     * For more information about shutting down thread pools see the {@link #shutdown(java.util.concurrent.ExecutorService)}
048     * and {@link #shutdownNow(java.util.concurrent.ExecutorService)}, and {@link #getShutdownAwaitTermination()} methods.
049     * Notice the details about using a graceful shutdown at fist, and then falling back to aggressive shutdown in case
050     * of await termination timeout occurred.
051     *
052     * @see ThreadPoolFactory
053     */
054    public interface ExecutorServiceManager extends ShutdownableService, StaticService {
055    
056        /**
057         * Gets the {@link ThreadPoolFactory} to use for creating the thread pools.
058         *
059         * @return the thread pool factory
060         */
061        ThreadPoolFactory getThreadPoolFactory();
062    
063        /**
064         * Sets a custom {@link ThreadPoolFactory} to use
065         *
066         * @param threadPoolFactory the thread pool factory
067         */
068        void setThreadPoolFactory(ThreadPoolFactory threadPoolFactory);
069    
070        /**
071         * Creates a full thread name
072         *
073         * @param name name which is appended to the full thread name
074         * @return the full thread name
075         */
076        String resolveThreadName(String name);
077    
078        /**
079         * Gets the thread pool profile by the given id
080         *
081         * @param id id of the thread pool profile to get
082         * @return the found profile, or <tt>null</tt> if not found
083         */
084        ThreadPoolProfile getThreadPoolProfile(String id);
085    
086        /**
087         * Registers the given thread pool profile
088         *
089         * @param profile the profile
090         */
091        void registerThreadPoolProfile(ThreadPoolProfile profile);
092    
093        /**
094         * Sets the default thread pool profile
095         *
096         * @param defaultThreadPoolProfile the new default thread pool profile
097         */
098        void setDefaultThreadPoolProfile(ThreadPoolProfile defaultThreadPoolProfile);
099    
100        /**
101         * Gets the default thread pool profile
102         *
103         * @return the default profile which are newer <tt>null</tt>
104         */
105        ThreadPoolProfile getDefaultThreadPoolProfile();
106    
107        /**
108         * Sets the thread name pattern used for creating the full thread name.
109         * <p/>
110         * The default pattern is: <tt>Camel (#camelId#) thread ##counter# - #name#</tt>
111         * <p/>
112         * Where <tt>#camelId#</tt> is the name of the {@link org.apache.camel.CamelContext}
113         * <br/>and <tt>#counter#</tt> is a unique incrementing counter.
114         * <br/>and <tt>#name#</tt> is the regular thread name.
115         * <br/>You can also use <tt>#longName#</tt> is the long thread name which can includes endpoint parameters etc.
116         *
117         * @param pattern the pattern
118         * @throws IllegalArgumentException if the pattern is invalid.
119         */
120        void setThreadNamePattern(String pattern) throws IllegalArgumentException;
121    
122        /**
123         * Gets the thread name patter to use
124         *
125         * @return the pattern
126         */
127        String getThreadNamePattern();
128    
129        /**
130         * Sets the time to wait for thread pools to shutdown orderly, when invoking the
131         * {@link #shutdown()} method.
132         * <p/>
133         * The default value is <tt>10000</tt> millis.
134         *
135         * @param timeInMillis time in millis.
136         */
137        void setShutdownAwaitTermination(long timeInMillis);
138    
139        /**
140         * Gets the time to wait for thread pools to shutdown orderly, when invoking the
141         * {@link #shutdown()} method.
142         * <p/>
143         * The default value is <tt>10000</tt> millis.
144         *
145         * @return the timeout value
146         */
147        long getShutdownAwaitTermination();
148    
149        /**
150         * Creates a new daemon thread with the given name.
151         *
152         * @param name     name which is appended to the thread name
153         * @param runnable a runnable to be executed by new thread instance
154         * @return the created thread
155         */
156        Thread newThread(String name, Runnable runnable);
157    
158        /**
159         * Creates a new thread pool using the default thread pool profile.
160         *
161         * @param source the source object, usually it should be <tt>this</tt> passed in as parameter
162         * @param name   name which is appended to the thread name
163         * @return the created thread pool
164         */
165        ExecutorService newDefaultThreadPool(Object source, String name);
166    
167        /**
168         * Creates a new scheduled thread pool using the default thread pool profile.
169         *
170         * @param source the source object, usually it should be <tt>this</tt> passed in as parameter
171         * @param name   name which is appended to the thread name
172         * @return the created thread pool
173         */
174        ScheduledExecutorService newDefaultScheduledThreadPool(Object source, String name);
175    
176        /**
177         * Creates a new thread pool using the given profile
178         *
179         * @param source   the source object, usually it should be <tt>this</tt> passed in as parameter
180         * @param name     name which is appended to the thread name
181         * @param profile the profile with the thread pool settings to use
182         * @return the created thread pool
183         */
184        ExecutorService newThreadPool(Object source, String name, ThreadPoolProfile profile);
185    
186        /**
187         * Creates a new thread pool using using the given profile id
188         *
189         * @param source    the source object, usually it should be <tt>this</tt> passed in as parameter
190         * @param name      name which is appended to the thread name
191         * @param profileId the id of the profile with the thread pool settings to use
192         * @return the created thread pool, or <tt>null</tt> if the thread pool profile could not be found
193         */
194        ExecutorService newThreadPool(Object source, String name, String profileId);
195    
196        /**
197         * Creates a new thread pool.
198         * <p/>
199         * Will fallback and use values from the default thread pool profile for keep alive time, rejection policy
200         * and other parameters which cannot be specified.
201         *
202         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
203         * @param name        name which is appended to the thread name
204         * @param poolSize    the core pool size
205         * @param maxPoolSize the maximum pool size
206         * @return the created thread pool
207         */
208        ExecutorService newThreadPool(Object source, String name, int poolSize, int maxPoolSize);
209    
210        /**
211         * Creates a new single-threaded thread pool. This is often used for background threads.
212         * <p/>
213         * Notice that there will always be a single thread in the pool. If you want the pool to be
214         * able to shrink to no threads, then use the <tt>newThreadPool</tt> method, and use
215         * 0 in core pool size, and 1 in max pool size.
216         *
217         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
218         * @param name        name which is appended to the thread name
219         * @return the created thread pool
220         */
221        ExecutorService newSingleThreadExecutor(Object source, String name);
222    
223        /**
224         * Creates a new cached thread pool.
225         * <p/>
226         * <b>Important:</b> Using cached thread pool is discouraged as they have no upper bound and can overload the JVM.
227         *
228         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
229         * @param name        name which is appended to the thread name
230         * @return the created thread pool
231         */
232        ExecutorService newCachedThreadPool(Object source, String name);
233    
234        /**
235         * Creates a new fixed thread pool.
236         *
237         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
238         * @param name        name which is appended to the thread name
239         * @param poolSize    the core pool size
240         * @return the created thread pool
241         */
242        ExecutorService newFixedThreadPool(Object source, String name, int poolSize);
243    
244        /**
245         * Creates a new scheduled thread pool.
246         *
247         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
248         * @param name        name which is appended to the thread name
249         * @param poolSize    the core pool size
250         * @return the created thread pool
251         */
252        ScheduledExecutorService newScheduledThreadPool(Object source, String name, int poolSize);
253    
254        /**
255         * Creates a new single-threaded thread pool. This is often used for background threads.
256         *
257         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
258         * @param name        name which is appended to the thread name
259         * @return the created thread pool
260         */
261        ScheduledExecutorService newSingleThreadScheduledExecutor(Object source, String name);
262        
263        /**
264         * Creates a new scheduled thread pool using a profile
265         *
266         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
267         * @param name        name which is appended to the thread name
268         * @param profile     the profile with the thread pool settings to use
269         * @return created thread pool
270         */
271        ScheduledExecutorService newScheduledThreadPool(Object source, String name, ThreadPoolProfile profile);
272    
273        /**
274         * Creates a new scheduled thread pool using a profile id
275         *
276         * @param source      the source object, usually it should be <tt>this</tt> passed in as parameter
277         * @param name        name which is appended to the thread name
278         * @param profileId   the id of the profile with the thread pool settings to use
279         * @return created thread pool
280         */
281        ScheduledExecutorService newScheduledThreadPool(Object source, String name, String profileId);
282    
283        /**
284         * Shutdown the given executor service (<b>not</b> graceful).
285         * <p/>
286         * This implementation will issues a regular shutdown of the executor service,
287         * ie calling {@link java.util.concurrent.ExecutorService#shutdown()} and return.
288         *
289         * @param executorService the executor service to shutdown
290         * @see java.util.concurrent.ExecutorService#shutdown()
291         */
292        void shutdown(ExecutorService executorService);
293    
294        /**
295         * Shutdown the given executor service graceful at first, and then aggressively
296         * if the await termination timeout was hit.
297         * <p/>
298         * Will try to perform an orderly shutdown by giving the running threads
299         * time to complete tasks, before going more aggressively by doing a
300         * {@link #shutdownNow(java.util.concurrent.ExecutorService)} which
301         * forces a shutdown. The {@link #getShutdownAwaitTermination()}
302         * is used as timeout value waiting for orderly shutdown to
303         * complete normally, before going aggressively.
304         *
305         * @param executorService the executor service to shutdown
306         * @see java.util.concurrent.ExecutorService#shutdown()
307         * @see #getShutdownAwaitTermination()
308         */
309        void shutdownGraceful(ExecutorService executorService);
310    
311        /**
312         * Shutdown the given executor service graceful at first, and then aggressively
313         * if the await termination timeout was hit.
314         * <p/>
315         * Will try to perform an orderly shutdown by giving the running threads
316         * time to complete tasks, before going more aggressively by doing a
317         * {@link #shutdownNow(java.util.concurrent.ExecutorService)} which
318         * forces a shutdown. The parameter <tt>shutdownAwaitTermination</tt>
319         * is used as timeout value waiting for orderly shutdown to
320         * complete normally, before going aggressively.
321         *
322         * @param executorService the executor service to shutdown
323         * @param shutdownAwaitTermination timeout in millis to wait for orderly shutdown
324         * @see java.util.concurrent.ExecutorService#shutdown()
325         */
326        void shutdownGraceful(ExecutorService executorService, long shutdownAwaitTermination);
327    
328        /**
329         * Shutdown now the given executor service aggressively.
330         * <p/>
331         * This implementation will issues a regular shutdownNow of the executor service,
332         * ie calling {@link java.util.concurrent.ExecutorService#shutdownNow()} and return.
333         *
334         * @param executorService the executor service to shutdown now
335         * @return list of tasks that never commenced execution
336         * @see java.util.concurrent.ExecutorService#shutdownNow()
337         */
338        List<Runnable> shutdownNow(ExecutorService executorService);
339    
340        /**
341         * Awaits the termination of the thread pool.
342         * <p/>
343         * This implementation will log every 2nd second at INFO level that we are waiting, so the end user
344         * can see we are not hanging in case it takes longer time to terminate the pool.
345         *
346         * @param executorService            the thread pool
347         * @param shutdownAwaitTermination   time in millis to use as timeout
348         * @return <tt>true</tt> if the pool is terminated, or <tt>false</tt> if we timed out
349         * @throws InterruptedException is thrown if we are interrupted during waiting
350         */
351        boolean awaitTermination(ExecutorService executorService, long shutdownAwaitTermination) throws InterruptedException;
352    
353    }