Announcement Announcement Module
Collapse
No announcement yet.
Need advice on "Retry Advice" :) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Need advice on "Retry Advice" :)

    Hi

    I would like to have more understanding on how I can use Spring Integration's "Retry Advice" out-of-box component for my use case.

    My use case goes as below:

    I've a bean (aka, a service-activator) that invokes an external Service via REST or JMS protocol (the logic to decide which protocol to be used is based on some internal business logic).
    The external service is a kind-of Poller service to which I pass a job id and it returns back one of the status code among: CMP for completed, PND for Pending, FLD for Failed, depending on the current state of job for which job id was passed.
    My requirement is to keep invoking this external service untilI receive a status code of CMP or FLD from it.

    To implement this use case using Spring Integration components, I believe use of <int:request-handler-advice-chain> can be a good approach.
    I can use this advice chain inside my service-activator.

    Question 1 - Will that be a correct step ?

    Also I think use of "Simple Stateless Retry" or "Simple Stateless Retry with recovery" should fit the use-case best. Question 2 - Is that a correct thought ?

    Question 3 - What is the criteria for a Retry Advice to get invoked ? Does it get invoked only when a RuntimeException gets thrown from the component inside which it is embedded ?
    In other words, taking my use case as an example, Retry will happen only when a RuntimeException occurs inside my service-activator ?

    Question 4 - Assuming that the answer to my Question 3 is a "yes", to implement my use case, should I be throwing a RuntimeException from the service activator whenever the status returned from external service is PND so that retry advice can be applied ?

    Question 5 - Assuming that I go for one of the retry approach mentioned above (i.e., either of "Simple Stateless Retry" or "Simple Stateless Retry with recovery"), how do I ensure that retry happens infinitely until I get a CMP/FLD status from Service ?
    From the reference doc and examples provided, I find that the default retry count is 3.
    Also I've the understanding that I can increase the number of retry counts using a customized RetryTemplate, but how can I have the retry mechanism go on endlessly until unless I get a CMP/FLD status from external service ?

    Question 6 - Lastly, I believe it is possible, but just want to reconfirm:

    Can <int:request-handler-advice-chain> be part of a <service-activator> component inside a <int:chain> ?

    In other words, is below possible ?

    <int:chain>
    <int:service-activator ref="sa1" method="method1"/>
    <int:transformer ...../>
    <int:service-activator ref="sa2" method="method2">
    <int:request-handler-advice-chain>
    <bean class="org.springframework.integration.handler.adv ice.RequestHandlerRetryAdvice" />
    </int:request-handler-advice-chain>
    <int:filter ..... />
    <int:service-activator ref="sa3" method="method3"/>
    </int:chain>

    Many thanks in advance for all the suggestions and guidance.

    PS : Answers to my questions 1 & 2 may not be a straightforward yes/no because it may require more in-depth functionality details of my use case, but I just want to know if my thoughts are in correct direction.

    Best Regards
    LB
    Last edited by lbvirgo; Jun 6th, 2013, 02:36 PM.

  • #2
    Yes to all.

    Spring Retry provides an 'AlwaysRetryPolicy' - just inject that into the RetryTemplate.

    Comment


    • #3
      Thanks Gary for the quick response.

      From the example provided in reference doc for customized RetryTemplate
      Code:
      <bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
      	<property name="retryPolicy">
      		<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
      			<property name="maxAttempts" value="4" />
      		</bean>
      	</property>
      	<property name="backOffPolicy">
      		<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
      			<property name="initialInterval" value="1000" />
      			<property name="multiplier" value="5" />
      		</bean>
      	</property>
      </bean>
      can you pls let me know where exactly 'AlwaysRetryPolicy' property has to be injected in the "retryTemplate" bean and with what value ?

      Comment


      • #4
        Just replace

        Code:
        	<property name="retryPolicy">
        		<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
        			<property name="maxAttempts" value="4" />
        		</bean>
        	</property>
        with
        Code:
        	<property name="retryPolicy">
        		<bean class="org.springframework.retry.policy.AlwaysRetryPolicy" />
        	</property>

        Comment


        • #5
          Thanks again.

          A quick question - Is it possibly to retry an entire "chain" as one unit ?

          Comment


          • #6
            Hi!
            Is it possibly to retry an entire "chain" as one unit ?
            No, you can't. <int:request-handler-advice-chain> was designed for one MessageHandler.handlerMessage, not to affect others handlers in the message flow. There is no difference how do you define your flow: channel+endpoint or channel+chain. The logic of MessageHandler is the same. So, we should apply the same rules for top MessageHandlers and with <chain>.
            And don't forget: you always can decompose any <chain> to separate endpoints without breaking entire message flow.
            But now imagine, if we allow to add <int:request-handler-advice-chain> and further you deside to pull some handler from <chain> as separate ednpoint. And, yeh, the message flow doesn't work as expected...

            Cheers,
            Artem

            Comment


            • #7
              That makes sense. Thanks for the clarification.

              LB

              Comment


              • #8
                I read again your response and wanted some inputs on your statement

                "you always can decompose any <chain> to separate endpoints without breaking entire message flow."

                I wanted to know is there any kind-of benchmark as to how many <chain> elements we can incorporate without impacting the performance ? I understand that it is a very open question and will depend on various other parameters but just want to know should I always think twice before incorporating a new chain in my flow ?

                Thanks

                LB

                Comment


                • #9
                  The <chain> incapsulates some kind of sub-flow when handlers send message to each other via some DirrectChannel implementation.
                  So, there is no difference if your 'decomposed' <chain> provide the same: DirrectChannels between endpoints.
                  And yes: you should think twice, and not only about <chain>.
                  Martin Fowler said once:
                  I'm lazy developer, so I typing code to implement a task, and then I feed it with Refactoring.
                  From my practice: I more lazy. I go from wall to wall more than I typing. And it's still very often I remain unhappy, that I have to break my <chain>s .
                  Try do not think about <chain> at all: it's just some 'minimizer' of code from big height.

                  Comment

                  Working...
                  X