1 2 Previous Next 17 Replies Latest reply on Jan 20, 2009 10:54 AM by sgc

    Difference between Sync and Async delivery in ServiceInvoker

    edgar.silva

      Hi,

      I am using a ServiceInvoker, which I supose is quite appropriated for some WebApplications or even Desktop clients.

      When I use: deliverAsync(esbMessage), everything works fine, I can just see the message handling/process once.

      But, when I use deliverSync(esbMessage,xxxx), I can see the message handling twice(not duplicated because the JMS_ID is different), an exception occurs, and I must declare an "orginial_quee+_reply" quee just for it.

      Anybody knows where may I find it well documented? Or if possible explain these differences here?

      Exception:

      Exception in thread "main" org.jboss.soa.esb.listeners.message.MessageDeliverException: Failed to deliver message [header: .....


      Cheers

      Edgar

        • 1. Re: Difference between Sync and Async delivery in ServiceInv
          kconner

          If you are using synchronous communication then the calling thread will wait for a response before returning. If it has not received a response within a specified period then it will attempt to redeliver the message and this would explain the two messages you are seeing (the response has been lost).

          From what you are describing it sounds as if you need to create the reply queue. This would normally share the same name as the request queue with '_reply' appended to it.

          • 2. Re: Difference between Sync and Async delivery in ServiceInv
            kconner

            I should also add that it is better to use asynchronous communications if possible, the performance is better and it does not block threads.

            This all depends on the architecture of your application though.

            • 3. Re: Difference between Sync and Async delivery in ServiceInv
              bmachado

              Hi Kevin,

              Thanks for the answear, I will check about the timeout here.

              In my architecture, try imagine an web application, where I hava a BackingBean that waits for a response in the same transaction, and this response is provided by ESB.

              I think I can use something related with "Comet concept", due to use Asynch mode.

              Would you suggest an alternative for my first scenario, where I need send a response for a sinchronous transaction (an http one).

              Thanks

              Edgar

              • 4. Re: Difference between Sync and Async delivery in ServiceInv
                haagenhasle

                 

                "Kevin.Conner@jboss.com" wrote:
                If you are using synchronous communication then the calling thread will wait for a response before returning. If it has not received a response within a specified period then it will attempt to redeliver the message and this would explain the two messages you are seeing (the response has been lost).

                From what you are describing it sounds as if you need to create the reply queue. This would normally share the same name as the request queue with '_reply' appended to it.


                In this thread: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=123451&postdays=0&postorder=asc&start=10 you explained that for sync calls, redelivery was not done. When I read what you wrote above, at first I thought you were contradicting yourself. But when I think about I a little bit more, I understand that perhaps I have not understood the concepts correctly. In my original post we were discussing exceptions, but in this case you are discussing timeouts. Perhaps the redeliveries that I saw were because of timeouts...

                But can the redeliery be configured/turned off? I don't really want automatic redlivery when SI.deliverySync times out.


                Regards, Haagen[/url]

                • 5. Re: Difference between Sync and Async delivery in ServiceInv
                  de_pauw_luc

                  I have looked around a bit in the code of the esb and traced the message chain.
                  If you got for example Service1 -> Service2 -> (ServiceInvoke sync) -> Service3 ...
                  the Service3 will reply on the queue from Service1.
                  So Service2 times out and resends the request.

                  In the code of ServiceInvoke there's a test if there's a replyTo EPR in the message header,
                  if so it uses this one if not it takes the reply EPR used to deliver the attempt.
                  In case of service2 the message has already a reply EPR so it copies this one. Service3 will reply on this EPR.

                  See code

                   /**
                   * Attempt to deliver the supplied message using the supplied EPR.
                   *
                   * @param message The message to be delivered.
                   * @param epr The EPR to be used in the delivery attempt.
                   * @return Returns the message (or a reply message if synchronous) if the message was delivered
                   * without error, otherwise null.
                   */
                   private Message attemptDelivery(Message message, EPR epr) throws FaultMessageException, MalformedEPRException {
                   TwoWayCourier courier = null;
                   if(synchronous){
                   logger.info("***SYNC");
                  }
                  else{
                   logger.info("***ASYNC");
                  
                  };
                   // Get a courier for the EPR...
                   try {
                   courier = getCourier(epr);
                   } catch (CourierException e) {
                   logger.debug("Courier lookup failed for EPR [" + epr + "] for Service [" + service + "] and Message ["+message.getHeader()+"].", e);
                   } catch (MalformedEPRException e) {
                   logger.warn("Badly formed EPR [" + epr + "] for Service [" + service + "] and Message ["+message.getHeader()+"]." + e.getMessage());
                  
                   throw e;
                   } catch (Throwable t) {
                   logger.warn("Unexpected exception during Courier lookup for EPR [" + epr + "] for Service [" + service + "] and Message ["+message.getHeader()+"].", t);
                   }
                  
                   // Try delivering the message using the courier we just looked up....
                  
                   if (courier != null) {
                   // make sure the message header does not change when we exit
                  
                   EPR currentEpr = message.getHeader().getCall().getTo();
                  
                   try {
                   EPR replyToEPR = message.getHeader().getCall().getReplyTo();
                   logger.info("**MSG REPLY TO [attemptdelivery]: " + replyToEPR);
                  
                   logger.info("**EPR REPLY TO [attemptdelivery]: " + getReplyToAddress(epr));
                  
                   message.getHeader().getCall().setTo(epr);
                  
                   if (synchronous) {
                   if (replyToEPR == null)
                   replyToEPR = getReplyToAddress(epr);
                  
                  
                   if (replyToEPR == null) {
                   logger.debug("Not using epr [" + epr + "] for Service [" + service + "] and Message ["+message.getHeader()+"]. No reply-to address available for synchronous response.");
                   return null;
                   }
                   message.getHeader().getCall().setReplyTo(replyToEPR);
                   }
                  ...
                  


                  I tried to fill in null as replyTo EPR in the message before ServiceInvoke, then service3 replies to service2,
                  but then the processing stops, doesn't bubble up to service1.

                  Anybody knows how to fix this ?

                  Thanks

                  Luc

                  • 6. Re: Difference between Sync and Async delivery in ServiceInv
                    kconner

                    The pipeline should be using the values from the initial call into the service. Which version of the ESB are you using?

                    • 7. Re: Difference between Sync and Async delivery in ServiceInv
                      de_pauw_luc

                       

                      "Kevin.Conner@jboss.com" wrote:
                      The pipeline should be using the values from the initial call into the service. Which version of the ESB are you using?


                      I'm using JBoss-esb server 4.2.1.GA.



                      • 8. Re: Difference between Sync and Async delivery in ServiceInv
                        haagenhasle

                         

                        "de_pauw_luc" wrote:

                        In the code of ServiceInvoke there's a test if there's a replyTo EPR in the message header,
                        if so it uses this one if not it takes the reply EPR used to deliver the attempt.
                        In case of service2 the message has already a reply EPR so it copies this one. Service3 will reply on this EPR.
                        [...]
                        I tried to fill in null as replyTo EPR in the message before ServiceInvoke, then service3 replies to service2,
                        but then the processing stops, doesn't bubble up to service1.

                        Anybody knows how to fix this ?

                        Thanks

                        Luc


                        I think I've seen the same thing as you, what I did to solve this was to create a new Message in Service2, and copy the data I need in Service3 from the original message over to the new message. When I get the reply back I copy the response-data from the Message I made back into the original message.

                        Regards, Haagen

                        • 9. Re: Difference between Sync and Async delivery in ServiceInv
                          de_pauw_luc

                           



                          I think I've seen the same thing as you, what I did to solve this was to create a new Message in Service2, and copy the data I need in Service3 from the original message over to the new message. When I get the reply back I copy the response-data from the Message I made back into the original message.

                          Regards, Haagen


                          You haven't got some code snippet how to copy the message ?

                          Thanks!

                          Luc

                          • 10. Re: Difference between Sync and Async delivery in ServiceInv
                            haagenhasle

                            Well, it's really nothing fancy. And I don't copy the entire message, I just take the data I need. Here's one example:

                            Message newOperationMsg = MessageFactory.getInstance().getMessage(MessageType.JBOSS_XML);
                            transferParameter(originalMsg, newOperationMsg, key);

                            where transferParameter looks like this:
                            protected void transferParameter(Message fromMsg, Message toMsg, String key) {
                             toMsg.getBody().add(key, fromMsg.getBody().get(key));
                             }


                            This might not be suitable for you though, I guess it depends on your usecase..

                            Regards, Haagen

                            • 11. Re: Difference between Sync and Async delivery in ServiceInv
                              de_pauw_luc

                               



                              This might not be suitable for you though, I guess it depends on your usecase..

                              Regards, Haagen


                              Thanks Haagen this solved the problem. It's clear that for every ServiceInvoker you have to copy the message if not the reply is send to a wrong queue.

                              • 12. Re: Difference between Sync and Async delivery in ServiceInv
                                kconner

                                You should not need to copy the message but what you do need to make sure is that the replyTo/faultTo headers are configured correctly before calling SI.

                                The pipeline you are executing in should have stored the original values before any actions were executed, these are then used at the end of the pipeline to create any response/fault message.

                                • 13. Re: Difference between Sync and Async delivery in ServiceInv
                                  de_pauw_luc

                                  Hi Kevin,

                                  Our pipeline looks like this:

                                  SoapUI -> ESB webservice -> router action on gateway -> another router action to other esb project -> action

                                  It then should bubble up to soapui again.

                                  The router actions all do a ServiceInvoke and the just pass the same message without modifications to the header..

                                  Could you give/point me to an example on how to set the replyTo
                                  EPR ?

                                  When the headers are empty, as with a new message the ServiceInvoker picksup correctly the replyTo EPR... So should it not be a task of ServiceInvoker to fill in these values correctly ? Since it's a sync msg it should always return to it's origin not ?

                                  Thanks

                                  Luc

                                  • 14. Re: Difference between Sync and Async delivery in ServiceInv
                                    kconner

                                    If you are using our routers then you should be marking those services as OneWay. This would pass the message on to the other services and allow the final response to be sent back to the real originator.

                                    From what you are describing though, this is not the case. You are referring to synchronous invocations which would suggest you are using your own router.

                                    Is there any reason why you cannot use asynchronous invocations? They are likely to simplify your application and improve performance. From your diagram it looks like the original ESB webservice invocation may be the only point at which the invocation needs to be synchronous.

                                    If you can send me an example of your application then I can take a look at it and advise further.

                                    1 2 Previous Next