camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Camel 2.3 - ThreadPool Configuration
Date Tue, 16 Mar 2010 13:57:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/Camel+2.3+-+ThreadPool+Configuration">Camel
2.3 - ThreadPool Configuration</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h2><a name="Camel2.3-ThreadPoolConfiguration-DesignNotesforThreadPoolConfiguration"></a>Design
Notes for ThreadPool Configuration</h2>

<p><a href="https://issues.apache.org/activemq/browse/CAMEL-1588" rel="nofollow">CAMEL-1588</a>
is the ticket for a new and improved thread pool configuration for Apache Camel. Its intended
for Camel 2.3.</p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Scope"></a>Scope</h3>

<p>Camel uses thread pool in various places such as <a href="/confluence/display/CAMEL/EIP"
title="EIP">EIP</a> patterns, <a href="/confluence/display/CAMEL/Components" title="Components">Components</a>,
<a href="/confluence/display/CAMEL/Async" title="Async">Async</a> API and whatnot.
The aim is to improved and allow easier to configure those thread pools in a more streamlined
manner. The goal is to offer both a fine grained configuration where you can tweak individual
pools and have more coarse grained configuration with fallback to <em>global</em>
settings etc.</p>

<h4><a name="Camel2.3-ThreadPoolConfiguration-Outsidescope"></a>Outside
scope</h4>

<p>Some components provides their own thread pool configuration and management which
Camel of course cannot and should not try to tailor with. For example <a href="/confluence/display/CAMEL/Jetty"
title="Jetty">Jetty</a> is such an example.</p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-UsagesofthreadpoolsinCamel"></a>Usages
of thread pools in Camel</h3>

<p>Currently Camel uses thread pools in <b>camel-core</b> in the following
areas:</p>
<ul class="alternate" type="square">
	<li><tt>DefaultComponent</tt> - Optional thread pool for components in
need of such</li>
	<li><tt>DefaultEndpoint</tt> - Optional thread pool for endpoints in need
of such</li>
	<li><tt>DefaultProducerTemplate</tt> - Used by the <a href="/confluence/display/CAMEL/Async"
title="Async">Async</a> API of this template</li>
	<li><tt>ScheduledPollConsumer</tt> - Needs a <tt>ScheduledExecutorService</tt>
to schedule its tasks</li>
	<li><tt>RecipientListDefinition</tt> - The <a href="/confluence/display/CAMEL/Recipient+List"
title="Recipient List">Recipient List</a> EIP pattern</li>
	<li><tt>SplitDefinition</tt> - The <a href="/confluence/display/CAMEL/Splitter"
title="Splitter">Splitter</a> EIP pattern</li>
	<li><tt>ThreadsDefinition</tt> - The <tt>threads</tt> DSL</li>
	<li><tt>ToDefinition</tt> - Used by the <tt>toAsync</tt> variation</li>
	<li><tt>WireTapDefinition</tt> - The <a href="/confluence/display/CAMEL/Wire+Tap"
title="Wire Tap">Wire Tap</a> EIP pattern</li>
	<li><tt>MulticastProcessor</tt> - The underlying thread pool</li>
	<li><tt>OnCompletionProcessor</tt> - For sending async on completion routes</li>
	<li><tt>SendAsyncProcessor</tt> - The <tt>toAsync</tt> processor
variation</li>
	<li><tt>ThreadsProcessor</tt> - The underlying thread pool</li>
	<li><tt>WireTapProcessor</tt> - For sending async wire taps</li>
	<li><tt>SedaConsumer</tt> - To support the <tt>concurrentConsumers</tt>
and <tt>multipleConsumers</tt> options (uses separate pools)</li>
</ul>


<h3><a name="Camel2.3-ThreadPoolConfiguration-Existingconfiguration"></a>Existing
configuration</h3>

<p>You can configure the thread pool using the <b>setExecutorService</b>
setter methods that usually exists on those places where its in use. Some EIP patterns offer
a <tt>executorServiceRef</tt> option to refer to some pool to be looked up in
the <a href="/confluence/display/CAMEL/Registry" title="Registry">Registry</a>.</p>

<p>We should ensure all EIPs can be configured to use a custom thread pool in a nice
and easy way. <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-UsingdefaultThreadPools"></a>Using
default ThreadPools</h3>

<p>We should use <tt>CachedThreadPool</tt> from the JDK Core as its the
best general purpose pool for many short lived tasks, which is what Camel really does. Processing
many messages in a short live.  <b>DONE</b></p>

<p>Only used SingleExecutorService for background tasks, and ScheduledExecutorService
for scheduled tasks <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-ThreadPoolscope"></a>ThreadPool
scope</h3>

<p>It should be possible to configure a thread pool on either per CamelContext level
or per Route level, such as you can do with AutoStartup and the likes.<br/>
Then you can say, eg this route should use this pool, which have 20/50 in the pool size etc.
<b>CHANGE OF PLAN</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Threadpoolconfigurationbyrules"></a>Thread
pool configuration by rules</h3>

<p>It should be possible to to define a set of rules which matches which thread pool
a given source should use.<br/>
It should be pattern based so you can say all EIPs should use this pool, all endpoints that
pool etc.</p>

<p>A ruleset something like this:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;threadPoolRule route=<span class="code-quote">"*"</span> source=<span
class="code-quote">"Aggregator"</span> executorServiceRef=<span class="code-quote">"myAggPool"</span>/&gt;
&lt;threadPoolRule route=<span class="code-quote">"*"</span> source=<span
class="code-quote">"To"</span> executorServiceRef=<span class="code-quote">"mySendPool"</span>/&gt;
&lt;threadPoolRule route=<span class="code-quote">"route3"</span> source=<span
class="code-quote">"*"</span> executorServiceRef=<span class="code-quote">"myRoute3Pool"</span>/&gt;
</pre>
</div></div>

<p>Where it will match against route first, so if we got a route3 then it will pick
among those<br/>
It should be possible to use wildcard and reg exp in the <tt>route</tt> and <tt>source</tt>
attributes.</p>

<p>Status: Consider for the future</p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Defaultthreadpoolprofile"></a>Default
thread pool profile</h3>

<p>It should be possible to set a default <tt>ThreadPoolProfile</tt> which
Camel will use when creating thread pools for the EIPs and whatnot. Then you can set default
settings and have that leveraged out of the box.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;threadPoolProfile id=<span class="code-quote">"myDefaultProfile"</span>
                           defaultProfile=<span class="code-quote">"true"</span>
                           poolSize=<span class="code-quote">"5"</span> keepAliveTime=<span
class="code-quote">"25"</span> maxPoolSize=<span class="code-quote">"15"</span>
maxQueueSize=<span class="code-quote">"250"</span> rejectedPolicy=<span class="code-quote">"Abort"</span>/&gt;
</pre>
</div></div>

<p>If none defined, then Camel should use a sensible default of</p>
<ul class="alternate" type="square">
	<li>poolSize = 10</li>
	<li>maxPoolSize = 20</li>
	<li>keepAliveTime = 60 seconds</li>
	<li>maxQueueSize = -1 (unbounded)</li>
	<li>rejectedPolicy = CallerRuns</li>
</ul>


<p>And it should validate that only <b>one</b> <tt>defaultProfile=true</tt>
can be set.</p>

<p>Status: <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Theproblemwithshutdownandrestartingpools"></a>The
problem with shutdown and restarting pools</h3>

<p>The ExecutorService API does not allow to restart a thread pool, which is PITA. So
we need to find a better strategy for stopping vs. shutdown.<br/>
Currently when we stop we also terminate the threadpool, and then re-create it on start. This
only works for default pools which we can create again.<br/>
But for custom thread pools we have no way to create them again as the pool is already created
when its given to us. </p>

<p>We may have to only shutdown thread pools if CamelContext is stopping. And then if
end user stop a route from JMX we can keep the thread pool around.<br/>
Only issue is the scheduled pool should stop scheduling tasks, which may be a bit more trickier
to avoid.</p>

<p>We have introduced a <tt>ShutdownableService</tt> to expose a <tt>shutdown</tt>
method which services can implement for their shutdown logic.<br/>
Then we can only shutdown thread pools in <tt>doShutdown()</tt> and not as before
in <tt>doStop()</tt>.</p>

<p>By letting Camel keep track of created thread pool, then Camel knows which pools
shutdown when its stopping. Then the need for <tt>doShutdown</tt> is not as apparent
as before, but its good to have this state in the lifecycles as well, for future needs.</p>

<p>Status: <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-TheproblemwithComponent%2CEndpoint"></a>The
problem with Component, Endpoint</h3>

<p>The DefaultComponent and DefaultEndpoint exposes API to get an ExecutorService. We
should remove these API as you should use <tt>ExecutorServiceStrategy</tt> from
<tt>CamelContext</tt> to obtain a thread pool. <b>DONE</b></p>


<h3><a name="Camel2.3-ThreadPoolConfiguration-Managedthreadpool"></a>Managed
thread pool</h3>

<p>Check whether the thread pools is managed by default and avail in JConsole. If not
we should probably at least expose some read-only data about the pools.</p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-SpringFactoryforcreatingcustompools"></a>Spring
Factory for creating custom pools</h3>

<p>Create a Spring XML DSL for defining thread pools using custom options such as corePoolSize,
maxPoolSize, keepAlive, thread name etc. <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-PluggableExecutorServiceSPI"></a>Pluggable
ExecutorService SPI</h3>

<p>We need a <tt>org.apache.camel.spi.ExeuctorServieStrategy</tt> which
is pluggable so end users can plugin their own strategy how to create thread pools. They can
leverage a WorkManager API from J2EE server etc. <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Customizablethreadname"></a>Customizable
thread name</h3>

<p>We should offer a simple pattern syntax so end users can customize the pattern the
thread name is created with: eg Something like: <tt>Camel Thread ${counter} - ${name</tt>}.
Where counter and suffix is dynamic parameters. The counter is an unique incrementing thread
counter. And name is provided from the source which as a way to name thread, such as a seda
endpoint uri. <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-EIPshouldmandateanExecutorService"></a>EIP
should mandate an ExecutorService</h3>

<p>If the EIPS which leverages a ExecutorService, mandates its being created and passed
to it, we can enforce creating/lookup the pool during route creation, which allows us to have
the route information as well, so we know which routes creates which pools. By passing in
<tt>null</tt> we loose this opportunity.<br/>
That is why all the EIP Processors should be refactored to have ExeuctorService as parameter.
<b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-LetCamelkeeptrackofcreatedpools"></a>Let
Camel keep track of created pools</h3>
<p>Using the <tt>DefaultExecutorServiceStrategy</tt> we can let Camel keep
track of the created pools, and thus also it can shutdown those when CamelContext is shutting
down. Then Camel is handling the lifecycle for the pools it creates. And if you pass in a
thread pool from an external system then you manage that lifecycle. Camel will in those cases
<b>not</b> shut it down. <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Sensibledefaults"></a>Sensible
defaults</h3>
<p>The <tt>CachedExecutorService</tt> by the JDK is maybe a bit aggressive
as its unbounded thread pool which essentially can create 1000s of threads if the sever is
not busy. But end users may want to have a reasonable max size, lets say 100. So we should
offer some sort of rule which you can configure what the default settings should be for thread
pools created by Camel. <b>DONE</b></p>

<h3><a name="Camel2.3-ThreadPoolConfiguration-Rejectionpolicy"></a>Rejection
policy</h3>
<p>We should add configuration about rejection policies for new tasks submitted to a
pool. The JDK has options for ABORT, RUN, WAIT, DISCARD etc. <b>DONE</b></p>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Camel+2.3+-+ThreadPool+Configuration">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=10387717&revisedVersion=19&originalVersion=18">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Camel+2.3+-+ThreadPool+Configuration?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message