...
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} |
Wiki Markup |
---|
{snippet:id=e2|lang=java|url=camel/trunk/tests/camel-itest/src/test/java/org/apache/camel/itest/async/HttpAsyncTest.java} |
...
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} |
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} |
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 | ||
---|---|---|
| ||
Mind that when using transactions its often required that the Exchange is processed entirely in the same thread, as the transaction manager often uses Notice: This does not apply to the |
...