简体   繁体   中英

camel: how can i send to an endpoint asynchronously

How can I send a message to an endpoint without waiting for that endpoint's route to be process (that is, my route should just dispatch the message and finish)?

Using wireTap or multicast is what you're after. A direct: endpoint will modify the Exchange for the next step no matter what ExchangePattern is specified. You can see by using this failing test:

public class StackOverflowTest extends CamelTestSupport {
    private static final String DIRECT_INPUT = "direct:input";
    private static final String DIRECT_NO_RETURN = "direct:no.return";
    private static final String MOCK_OUTPUT = "mock:output";
    private static final String FIRST_STRING = "FIRST";
    private static final String SECOND_STRING = "SECOND";

    @NotNull
    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from(DIRECT_INPUT)
                        .to(ExchangePattern.InOnly, DIRECT_NO_RETURN)
                        .to(MOCK_OUTPUT)
                        .end();

                from(DIRECT_NO_RETURN)
                        .bean(new CreateNewString())
                        .end();
            }
        };
    }

    @Test
    public void testShouldNotModifyMessage() throws JsonProcessingException, InterruptedException {
        final MockEndpoint myMockEndpoint = getMockEndpoint(MOCK_OUTPUT);
        myMockEndpoint.expectedBodiesReceived(FIRST_STRING);
        template.sendBody(DIRECT_INPUT, FIRST_STRING);
        assertMockEndpointsSatisfied();
    }

    public static class CreateNewString {
        @NotNull
        public String handle(@NotNull Object anObject) {
            return SECOND_STRING;
        }
    }
}

Now if you change the above to a wireTap:

                from(DIRECT_INPUT)
                    .wireTap(DIRECT_NO_RETURN)
                    .to(MOCK_OUTPUT)
                    .end();

and you'll see it works as expected. You can also use multicast:

                from(DIRECT_INPUT)
                    .multicast()
                    .to(DIRECT_NO_RETURN)
                    .to(MOCK_OUTPUT)
                    .end();

That might depend on what endpoints etc you are using, but one common method is to put a seda endpoint in between is one option.

from("foo:bar")
  .bean(processingBean)
  .to("seda:asyncProcess") // Async send
  .bean(moreProcessingBean)

from("seda:asyncProcess")
  .to("final:endpoint"); // could be some syncrhonous endpoint that takes time to send to. http://server/heavyProcessingService or what not.

The seda endpoint behaves like a queue, first in - first out. If you dispatch several events to a seda endpoint faster than the route can finish processing them, they will stack up and wait for processing, which is a nice behaviour.

You can use inOnly in your route to only send your message to an endpoint without waiting for a response. For more details see the request reply documentation or the event message documentation

from("direct:testInOnly").inOnly("mock:result");

you can use a ProducerTemplate 's asyncSend() method to send an InOnly message to an endpoint...

template.asyncSend("direct:myInOnlyEndpoint","myMessage");

see http://camel.apache.org/async.html for some more details

wireTap(endpoint)就是答案。

https://people.apache.org/~dkulp/camel/async.html

Both for InOnly and InOut you can send sync or async. Seems strange that you can send InOnly but async, but at last here it explains that it waits for Camel processing and then fire and forget.

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

Method Returns Description
setExecutorService void Is used to set the Java ExecutorService. Camel will by default provide a ScheduledExecutorService with 5 thread in the pool.
asyncSend Future 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 Future 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 Future 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 T Is used to get the result from the asynchronous thread using the Java Concurrency Future handle.

The Async Client API with callbacks In addition to the Client API from above Camel provides a variation that uses callbacks when the message Exchange is done.

Method Returns Description
asyncCallback Future In addition a callback is passed in as a parameter using the org.apache.camel.spi.Synchronization Callback. The callback is invoked when the message exchange is done.
asyncCallbackSendBody Future As above but for sending body only. This is a request only messaging style so no reply is expected. Uses the InOnly exchange pattern.
asyncCallbackRequestBody Future As above but for sending body only. This is a Request Reply messaging style so a reply is expected. Uses the InOut exchange pattern.

These methods also returns 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.

The Future API The java.util.concurrent.Future API have among others the following methods:

Method Returns Description
isDone boolean Returns a boolean whether the task is done or not. Will even return true if the tasks failed due to an exception thrown.
get() Object Gets the response of the task. In case of an exception was thrown the java.util.concurrent.ExecutionException is thrown with the caused exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM