You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Async

Available as of Camel 2.0

The asynchronous API in Camel have been rewritten for Camel 2.0, and the information on this page applies for Camel 2.0 and later.

A bit of background

The new Async API in Camel 2.0 leverages in much greater detail the Java Concurrency API and its support for executing tasks asynchronous.
Therefore the Camel Async API should be familiar for users with knowledge of the Java Concurrency API.

A few concepts to master

When doing messaging there are a few aspects to keep in mind.

First of all a caller can initiate a message exchange as either:

Request only is when the caller sends a message but do not expect any reply. This is also sometimes known as fire and forget or event message.

The Request Reply is then caller sends a message and then waits for a reply. This is like the Http protocol that we use every day when we surf the web.
We send a request to fetch a web page and wait until the reply message comes with the web content.

In Camel a message is labeled with a Message Exchange Pattern that labels whether its a request only or request reply message. Camel uses the JBI term for this an uses InOnly for the request only, and InOut for the request reply.

For both the request only and the request reply the routing in Camel can happen either:

  • synchronous
  • asynchronous

A sync is defined as the caller thread and the remaining routing and processing of the message is happening in the same thread and as sync the caller waits until this thread has done its work before the invocation can return to the caller and continue its work. This is illustrated in the diagram below:

On the other hand the asynchronous version is where the caller thread initiates the request and leave the further processing of the message in another thread, the asynchronous thread, and then immediately returns to the caller. Then the caller can continue doing other work and at the same time the asynchronous thread is processing the message. If we are using [Request Reply then at a later point in time the original caller can get hold of the response from the asynchronous thread. If we are using request only then there are no response but the caller can still get a kind of response as it can get information whether the asynchronous thread is done or failed due to an exception. This is illustrated in the diagram below:

In the following we will look at how to use this new Async API in Camel.

The Async API

Camel provides the Async API in the Producer Template where we have added about 10 new methods to Camel 2.0. We have listed the most important in the table below:

Method

Description

setExecutorService

Is used to set the Java ExecutorService. Camel will by default provide a ScheduledExecutorService with 5 thread in the pool.

asyncSend

Is used to send an async exchange to a Camel Endpoint. Camel will imeddiately return control to the caller thread after the task has been submitted to the executor service. This allows you to do other work while Camel processes the exchange in the other async thread.

asyncSendBody

As above but for sending body only. This is a request only messaging style so no reply is expected. Uses the InOnly exchange pattern.

asyncRequestBody

As above but for sending body only. This is a Request Reply messaging style so a reply is expected. Uses the InOut exchange pattern.

extractFutureBody

Is used to get the result from the asynchronous thread using the Java Concurrency Future handle.

The asyncSend and asyncRequest methods return a Future handle. This handle is what the caller must use later to retrieve the asynchronous response. You can do this by using the extractFutureBody method, or just use plain Java but invoke get() on the Future handle.

An example

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:

Error formatting macro: snippet: java.lang.NullPointerException

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:

Error formatting macro: snippet: java.lang.NullPointerException

All together it should give you the basic idea how to use this Async API and what it can do.

Using the Async DSL

TODO: About the async DSL.

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:

Endpoint endpoint = context.getEndpoint("http://slowserver.org/myservice");
Exchange exchange = endpoint.createExchange();
exchange.getIn().setBody("Order ABC");
// create a regular producer
Producer producer = endpoint.createProducer();
// send the exchange and wait for the reply as this is synchronous
producer.process(exchange);

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

Endpoint endpoint = context.getEndpoint("http://slowserver.org/myservice");
Exchange exchange = endpoint.createExchange();
exchange.getIn().setBody("Order ABC");
// create a regular producer
Producer producer = endpoint.createProducer();
// normally you will use a shared exectutor service with pools
ExecutorService executor = Executors.newSingleThreadExecutor();
// send it async with the help of this helper
Future<Exchange> future = AsyncProcessorHelper.asyncProcess(executor, producer, exchange);
// here we got the future handle and we can do other stuff while the exchange is being routed in the other asynchronous thread
...
// and to get the response we use regular Java Concurrency API
Exchange response = future.get();
  • No labels