Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

Note: As Camel always returns a Future handle for Async messaging to the client. The client can use this handler to get hold of the status of the processing whether the task is complete or an Exception occurred during processing. Note that the client is not required to do so, its perfect valid to just ignore the Future handle.

...

...

In case you want to know whether the Async Request Only failed, then you can use the Future handle and invoke get() and if it throws a ExecutionException then the processing failed. The caused exception is wrapped. You can invoke isDone() first to test whether the task is done or still in progress. Otherwise invoking get() will wait until the task is done.

...

These methods also returns the the Future handle in case you need them. The difference is that they invokes the callback as well when the Exchange is done being routed.

...

Suppose we want to call a HTTP service but it is usually slow and thus we do not want to block and wait for the response, as we can do other important computation. So we can initiate an Async exchange to the HTTP endpoint and then do other stuff while the slow HTTP service is processing our request. And then a bit later we can use the Future handle to get the response from the HTTP service. Yeah nice so lets do it:

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

When using the Camel API to create a producer and send an Exchange we do it like this:

...

...

But to do the same with Async we need a little help from a helper class, so the code is:

...

...

2) Using the Threads DSL

In Camel 2.0 the threads DSL replaces the old thread DSL.

...

Note: there's an issue with these two options in Camel 2.9 or earlier, that cause the UnitOfWork not to be triggered, so we discourage you from using these options in those Camel releases. This has been fixed in Camel 2.10.

...

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}

...

...

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 asynchronous thread cannot participate in the same transaction as the caller thread.

Note: 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 asynchronous messaging where the processing of the Exchange is still handled within transaction. It's only the client that submitted the Exchange that does not participate in the same transaction.

See Also