Hi, guys.  I've been following the "async" docs and examples and the few code 
snippets I could find online, but I'm still having trouble doing something that 
I would think is very common.

My use case is basically this:

1. I have a small route (call it "experiment") that hits an HTTP endpoint and 
returns the integer value returned by that endpoint.

2. I need to asynchronously call this "experiment" route from within a loop, or 
from a barrage of JMS messages, etc.

----------

To test this, I created a small separate service sitting on port 8090 with 
endpoint "/experiment?i=<value>".

The endpoint just calculates a delay, sleeps, and returns the delay:

    @GetMapping(value = "/experiment")
    public Integer sedaExperiment (@RequestParam(name = "i", required = true) 
Integer ival) throws InterruptedException
    {
        log.info(String.format("sedaExperiment: ival: %d", ival));
        delay = 10 + ival*10;
        log.info(String.format("sedaExperiment: %d - sleeping %d seconds...", 
ival, delay));
        Thread.sleep(delay * 1000L);
        log.info(String.format("sedaExperiment: %d - returning: %d", ival, 
delay));
        return delay;
    }

----------

In my calling app, my "experiment" route is simple enough:

        from("seda:experiment")
            .routeId("seda-experiment")
            .setHeader("val", simple("${body}"))
            .log(LoggingLevel.INFO, "Experiment: ${header.val}")
            .toD("http://localhost:8090/experiment?i=${header.val}";)
            .log(LoggingLevel.INFO, "Experiment: ${header.val} - results: 
${body}");

And here's where I call it in a loop:

        from("timer:experiment?repeatCount=1")
            .routeId("timer-experiment")
            .process(new Processor() {
                public void process(Exchange e) throws Exception {
                    ProducerTemplate prod = 
e.getContext().createProducerTemplate();
                    MyCallback callback = new MyCallback();
                    for ( int i = 1; i <= 3; i++ ) {
                        log.info(String.format("*** i = %d", i));
//                        prod.asyncSendBody("seda:experiment", i, callback);
//                        prod.asyncRequestBody("seda:experiment", i, callback);
//                        prod.asyncCallbackSendBody("seda:experiment", i, 
callback);
                        prod.asyncCallbackRequestBody("seda:experiment", i, 
callback);
//                        
prod.asyncCallbackSendBody("http://localhost:8090/experiment?i="+i, null, 
callback);
                    }
                }
            });

where 'callback' is:

    private static class MyCallback extends SynchronizationAdapter {
        @Override
        public void onComplete(Exchange exchange) {
            Integer result = exchange.getIn().getBody(Integer.class);
            log.info(String.format("ASYNC: Experiment: %d - results: %d", 99, 
result));
        }
    }

-------------------------

What ends up happening is that the "seda:experiment" route is called 
sequentially, with each call waiting for the service's endpoint's delay to 
finish.  Obviously not async...

Besides asyncCallbackRequestBody(), you can see I experimented with other async 
calls.  Nothing worked as desired.

The closest thing that worked was not calling my "seda:experiment" route but 
calling the endpoint directly:

asyncCallbackSendBody("http://localhost:8090/experiment?i="+i, null, callback);

This *did* kick off 3 simultaneous threads on the service side.  However, the 
results don't seem to be in the callback ('result' is null, not 20, 30, 40).  
But even if I could get the result in the callback, I'd *really* rather be able 
to call my route because the (real) route contains extra processing that I 
don't want to try replicating in the callback.

-------------------------

So what am I doing wrong?  I know this must be something people do ALL THE 
TIME...

As for the callback stuff, if I could call "seda:experiment" asynchronously, I 
wouldn't even need any of the "Callback" versions of any of the async*() calls. 
 The route does everything I need.  I just can't call it properly...

As always, thank you for any help.

Reply via email to