Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

First we define some routes in Camel. One for the HTTP service where we simulate a slow server as it takes at least 1 second to reply. And then other route that we want to invoke while the HTTP service is on route. This allows you to be able to process the two routes simultaneously:

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncTest.java}
And then we have the client API where we call the two routes and we can get the responses from both of them. As the code is based on unit test there is a bit of mock in there as well:
Wiki Markup
{snippet:id=e2|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncTest.java}
All together it should give you the basic idea how to use this Async API and what it can do.

...

The route is the same, so its just how the client initiate and send the messages that differs:

Wiki Markup
{snippet:id=e2|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpSyncTest.java}

Using the Async API with callbacks

...

First we define a route in Camel for the HTTP service where we simulate a slow server as it takes at least 1 second to reply.

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncCallbackTest.java}
Then we define our callback where we gather the responses. As this is based on an unit test it just gathers the responses in a list. This is a shared callback we use for every request we send in, but you can use your own individual or use an anonymous callback. The callback supports different methods, but we use onDone that is invoked regardless if the Exchange was processed successfully or failed. The org.apache.camel.spi.Synchronization API provides fine grained methods for onCompletion and onFailure for the two situations.
Wiki Markup
{snippet:id=e2|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncCallbackTest.java}
And then we have the client API where we call the HTTP service using asyncCallback 3 times with different input. As the invocation is Async the client will send 3 requests right after each other, so we have 3 concurrent exchanges in progress. The response is gathered by our callback so we do not have to care how to get the response.
Wiki Markup
{snippet:id=e3|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncCallbackTest.java}

Using the Async API with the Camel classic API

...

The threads DSL uses a thread pool which has a worker queue for tasks. When the worker queue gets full, the task is rejected. You can customize how to react upon this using the rejectedPolicy and callerRunsWhenRejected option. The latter is used for easily switch between the two most common and recommended settings. Either let the current caller thread execute the task (eg it will become synchronous), but also give time for the thread pool to process its current tasks, without adding more tasks - sort of self throttling. This is the default behavior. If setting callerRunsWhenRejected=false you use the Abort policy, which mean the task is rejected, and a RejectedExecutionException is set on the Exchange, and the Exchange will stop continue being routed, and its UnitOfWork will be regarded as failed.

...

Suppose we receive orders on a JMS queue. Some of the orders expect a reply while other do not (either a JMSReplyTo exists or not). And lets imagine to process this order we need to do some heavy CPU calculation. So how do we avoid the messages that does not expect a reply to block until the entire message is processed? Well we use the threads DSL to turn the route into multi threading asynchronous routing before the heavy CPU task. Then the messages that does not expect a reply can return beforehand. And the messages that expect a reply, well yeah they have to wait anyway. So this can be accomplished like the route below:

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncDslTest.java}

Warning
titleTransactions and threads DSL

Mind that when using transactions its often required that the Exchange is processed entirely in the same thread, as the transaction manager often uses ThreadLocal to store the intermediate transaction status. For instance Spring Transaction does this. So when using threads DSL the Exchange that is processed in the async thread cannot participate in the same transaction as the caller thread.

Notice: This does not apply to the ProducerTemplate Async API as such as the client usually does not participate in a transaction. So you can still use the Camel Client Async API and do async messaging where the processing of the Exchange is still handled within transaction. Its only the client that submitted the Exchange that does not participate in the same transaction.

...