camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > ToAsync
Date Wed, 12 May 2010 07:40:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/ToAsync">ToAsync</a></h2>
    <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >[ToAsync] is a new feature build into
the core of Camel 2.1. It sets the foundation base for non blocking asynchronous [Request
Reply] messaging with Camel. By *foundation* we mean that it has the moving pieces that makes
Camel [Components] leverage this in case they natively supports non blocking request reply.
At this time of writing its only the [Jetty] component that offers this. Over time we will
incorporate this into other components. However don&#39;t despair as Camel have fallback
support for simulating asynchronous request/reply in the Camel core, in cases where its not
supported natively in the Camel component used. <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">{info:title=May
change in the future} <br>The current [ToAsync] may change a bit in the future. We may
look into better ways for the caller to retrieve information about the progress of the [Exchange].
Currently the caller will just _transfer_ the [Exchange] to [ToAsync] and then continue. <br>{info}
<br> <br></td></tr>
            <tr><td class="diff-unchanged" >h3. How does it work? <br>Camel
now has a new DSL named {{toAsync}} in the Java DSL. And in Spring XML there is a new {{async}}
boolean attribute on the {{&lt;to&gt;}} XML tag. So in a Camel route you can leverage
this by just using a using this when sending to an endpoint when you do [Request Reply] messaging.
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <h2><a name="ToAsync-ToAsync"></a>ToAsync</h2>
<p><b>Available as of Camel 2.1</b></p>

<h3><a name="ToAsync-Background"></a>Background</h3>
<p><a href="/confluence/display/CAMEL/ToAsync" title="ToAsync">ToAsync</a>
is a new feature build into the core of Camel 2.1. It sets the foundation base for non blocking
asynchronous <a href="/confluence/display/CAMEL/Request+Reply" title="Request Reply">Request
Reply</a> messaging with Camel. By <b>foundation</b> we mean that it has
the moving pieces that makes Camel <a href="/confluence/display/CAMEL/Components" title="Components">Components</a>
leverage this in case they natively supports non blocking request reply. At this time of writing
its only the <a href="/confluence/display/CAMEL/Jetty" title="Jetty">Jetty</a>
component that offers this. Over time we will incorporate this into other components. However
don't despair as Camel have fallback support for simulating asynchronous request/reply in
the Camel core, in cases where its not supported natively in the Camel component used.</p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>May change
in the future</b><br />The current <a href="/confluence/display/CAMEL/ToAsync"
title="ToAsync">ToAsync</a> may change a bit in the future. We may look into better
ways for the caller to retrieve information about the progress of the <a href="/confluence/display/CAMEL/Exchange"
title="Exchange">Exchange</a>. Currently the caller will just <em>transfer</em>
the <a href="/confluence/display/CAMEL/Exchange" title="Exchange">Exchange</a>
to <a href="/confluence/display/CAMEL/ToAsync" title="ToAsync">ToAsync</a> and
then continue.</td></tr></table></div>

<h3><a name="ToAsync-Howdoesitwork%3F"></a>How does it work?</h3>
<p>Camel now has a new DSL named <tt>toAsync</tt> in the Java DSL. And in
Spring XML there is a new <tt>async</tt> boolean attribute on the <tt>&lt;to&gt;</tt>
XML tag. So in a Camel route you can leverage this by just using a using this when sending
to an endpoint when you do <a href="/confluence/display/CAMEL/Request+Reply" title="Request
Reply">Request Reply</a> messaging.</p>

<p>The route below is from a unit test in Camel. Notice the new <tt>toAsync</tt>
where we use this in action. What happens is that the message is send asynchronously to the
<tt>direct:bar</tt> endpoint. When the reply comes back the message is continued
being routed on <em>the other side</em> where its routed to the <tt>mock:result</tt>
endpoint. The number 5 indicates the thread pool size, so we have 5 concurrent consumers to
route the replies when they come back.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    from(<span class="code-quote">"direct:start"</span>).to(<span class="code-quote">"mock:a"</span>).toAsync(<span
class="code-quote">"direct:bar"</span>, 5).to(<span class="code-quote">"mock:result"</span>);

    from(<span class="code-quote">"direct:bar"</span>).to(<span class="code-quote">"mock:b"</span>).transform(constant(<span
class="code-quote">"Bye World"</span>));
</pre>
</div></div>

<p>This unit test is using the direct endpoint when sending using <tt>toAsync</tt>
and the direct component does <b>not</b> support non blocking request reply messaging
natively. And therefore Camel fallback to <em>simulate</em> this by transferring
the Exchange to an internal thread pool which handles the task of sending the Exchange. This
then frees the burden of the original thread to send the request and thus its work is offloaded
and it can continue. What it means is the that original thread is <b>not blocked</b>.
The internal thread pool will in the mean time send the request and handover the exchange
to the completed task queue when the reply comes back, and then the Exchange can be continued
routed in the route path. In this example it will just route to the <tt>mock:result</tt>
endpoint.</p>

<p>By using a component that truly supports non blocking <a href="/confluence/display/CAMEL/Request+Reply"
title="Request Reply">Request Reply</a> such as <a href="/confluence/display/CAMEL/Jetty"
title="Jetty">Jetty</a>, its in fact <a href="/confluence/display/CAMEL/Jetty"
title="Jetty">Jetty</a> itself that handles the <a href="/confluence/display/CAMEL/Request+Reply"
title="Request Reply">Request Reply</a> so the internal thread pool in Camel is <b>not</b>
used.</p>

<h4><a name="ToAsync-TheHTTPAsyncExample"></a>The <a href="/confluence/display/CAMEL/HTTP+Async+Example"
title="HTTP Async Example">HTTP Async Example</a></h4>
<p>In this example we use the following route:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
        &lt;route&gt;
            &lt;!-- we route from a direct endpoint --&gt;
            &lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;
            &lt;!-- log the request --&gt;
            &lt;to uri=<span class="code-quote">"log:+++ request +++"</span>/&gt;
            &lt;!-- then doing a non blocking async request/reply to the http server with
a pool of 10 threads --&gt;
            &lt;to uri=<span class="code-quote">"jetty:<span class="code-comment">//http://0.0.0.0:9123/myapp"</span>
async=<span class="code-quote">"<span class="code-keyword">true</span>"</span>
poolSize=<span class="code-quote">"10"</span>/&gt;
</span>            &lt;!-- the reply from the server is logged --&gt;
            &lt;to uri=<span class="code-quote">"log:+++  reply  +++"</span>/&gt;
            &lt;!-- and to our mock so we can <span class="code-keyword">assert</span>
we got all responses --&gt;
            &lt;to ref=<span class="code-quote">"result"</span>/&gt;
        &lt;/route&gt;
</pre>
</div></div>

<p>Notice how we have specified <tt>async="true"</tt> and <tt>poolSize="10"</tt>
in the <tt>&lt;to&gt;</tt> tag to leverage this.<br/>
To learn more see and try this example yourself.</p>

<h3><a name="ToAsync-HowthisworksinsideCamel"></a>How this works inside
Camel</h3>
<p>Camel uses the <tt>org.apache.camel.AsyncProcessor</tt> which is responsible
for processing the non blocking message.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
void process(Exchange exchange, AsyncCallback callback) <span class="code-keyword">throws</span>
Exception;
</pre>
</div></div>
<p>The idea is that you invoke the callback when the reply is ready. </p>

<p>The <tt>org.apache.camel.AsyncCallback</tt> has the following method</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
void onTaskCompleted(Exchange exchange);
</pre>
</div></div>
<p>which is the method to invoke when the reply is ready.</p>

<p>All the other moving parts is build directly into the core of Camel. So you do not
have to worry about that.<br/>
If you want to take a look its implemented in the <tt>org.apache.camel.processor.SendAsyncProcessor</tt>
class.</p>

<h3><a name="ToAsync-JettyHttpProducer"></a>JettyHttpProducer</h3>
<p>This class is currently the only implementation of this feature.</p>

<p>Basically you do implement the <tt>AsyncProcessor</tt> interface</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class JettyHttpProducer <span class="code-keyword">extends</span>
DefaultProducer <span class="code-keyword">implements</span> AsyncProcessor
</pre>
</div></div>

<p>And then invoke the callback when the reply is ready and populated on the Exchange.<br/>
See the class <tt>JettyContentExchange</tt> how this is implemented in <a href="/confluence/display/CAMEL/Jetty"
title="Jetty">Jetty</a>.</p>

<h3><a name="ToAsync-WhatifaComponentdoesnotsupportnonblocking%3F"></a>What
if a Component does not support non blocking?</h3>
<p>Many components does not naturally support non blocking <a href="/confluence/display/CAMEL/Request+Reply"
title="Request Reply">Request Reply</a>. The ones that does need to be improved in
Camel to support the <tt>AsyncProcessor</tt> to integrate with <a href="/confluence/display/CAMEL/ToAsync"
title="ToAsync">ToAsync</a>. If a component <b>does not</b> support 'non
blocking' (i.e. does not use <tt>AsyncProcessor</tt> then Camel will automatic
fallback and simulate this by using an internal thread pool that sends the request and blocks
until the reply is ready. Just as it did in the very first example on this page using the
direct endpoint.</p>

<h3><a name="ToAsync-Configuringthreadpooling"></a>Configuring thread pooling</h3>
<p>You configure the thread pool on the <tt>toAsync</tt> by either supply
a pool size as the 2nd parameter as we saw in the first example.<br/>
But you can also refer to a <tt>java.util.concurrent.ExecutorService</tt> as follows:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
from(<span class="code-quote">"direct:start"</span>).to(<span class="code-quote">"mock:a"</span>).toAsync(<span
class="code-quote">"direct:bar"</span>).executorServiceRef(<span class="code-quote">"mySharedPool"</span>).to(<span
class="code-quote">"mock:result"</span>);
</pre>
</div></div>

<p>In the Spring XML there is an attribute to refer to the thread pool</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    &lt;to uri=<span class="code-quote">"jetty:<span class="code-comment">//http://0.0.0.0:9123/myapp"</span>
async=<span class="code-quote">"<span class="code-keyword">true</span>"</span>
executorServiceRef=<span class="code-quote">"mySharedPool"</span>/&gt;</span>
</pre>
</div></div>

<h3><a name="ToAsync-Seealso"></a>See also</h3>
<ul class="alternate" type="square">
	<li><a href="/confluence/display/CAMEL/HTTP+Async+Example" title="HTTP Async Example">HTTP
Async Example</a> which shows the non blocking asynchronous in action using the <a
href="/confluence/display/CAMEL/Jetty" title="Jetty">Jetty</a> component. (natively
supported)</li>
	<li><a href="/confluence/display/CAMEL/CXF+Async+Example" title="CXF Async Example">CXF
Async Example</a> which shows the non blocking asynchronous in action using the <a
href="/confluence/display/CAMEL/CXF" title="CXF">CXF</a> component. (simulated in
Camel)</li>
	<li><a href="/confluence/display/CAMEL/Async" title="Async">Async</a> for
synchronous support in Camel routes and as Camel client API</li>
</ul>

    </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/ToAsync">View Online</a>
        |
        <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=5964693&revisedVersion=9&originalVersion=8">View
Changes</a>
                |
        <a href="http://cwiki.apache.org/confluence/display/CAMEL/ToAsync?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message