Orchestration "Retry" Pattern

Posted on November 16, 2009

One of the more difficult problems I’ve come across when working with BizTalk orchestrations in the past is what to do when communication with an external client fails. When a Send Port fails to connect after it’s configured number of try’s, for instance, an error message is generated by BTS. If you have not properly planned for this, the Message and Orchestration in question are both suspended in the BTS Admin Console and can not be properly resumed.

Once communication problems with the client have been resolved resuming the message may work, but messages sent back from the client will not connect with the original orchestration … causing yet another problem. Also, resuming the original orchestration will fail if it is waiting for a specific message type from the client. The solution is to implement a Retry Pattern.

The Retry Pattern is, quite simply, logic programmed into the Orchestration that we will suspend the orchestration so it can be properly resumed by an administrator. When resumed the orchestration will attempt to transmit the message again. Implementing the pattern involves use of a Scope shape (with Exception Handler), a Loop shape and a Decision shape that determines whether to suspend or not.

As depicted in the diagram below, the trick is to embed a Scope shape within a Loop. The Loop checks a RetryCounter variable (default equal to 0) to determine if its value is less than 2.
Retry Pattern Orchestration "Retry" Pattern
The Decide Shape checkes the RetryCounter to see if it is equal to 1. The 1st time through the check will resolve to “false” and the “Else” branch will be executed – which simply sets the RetryCounter to 1. Next the message is sent to the client. If the proper message is returned to our orchestration we set the RetryCounter to 2 which will cause the Loop to be broken, and we are done. However, if we do not receive a proper message and an exception is thrown, the Exception Hanlder will kick-in.

The Scope shape includes a catch-all Exception Handler using System.Exception. However, the Exception Handler does not execute any logic … it simply catches errors genereated by the two-way Send Port.  After the Exception Handler executes, the Loop shape continues the process. During the next check it still sees that the RetryCounter is less than 2 (it is 1) and proceeds to the Decide shape. This time the Decide shape resolves that the RetryCounter is equal to 1 and the “True” branch is executed. In the True branch we suspend the orchestration.

In my example we construct a custom error message that will be published to the message box for processing by a generic Exception Handling and Notification framework (Next Release of the HL7 toolkit – http://biztalkhl7toolkit.codeplex.com/). However, for our purposes what matters most is the Suspend shape. It’s purpose is quite simply to suspend the orchestration in a “suspended-resumable” state. So, we now have an orchestration that is suspended and available to be resumed once the root of our communication problems have been resolved. Just as important is the fact that the next step the resumed orchestration will attempt is to send the message again.

The only remaining question is what to do with the original suspended message. If you have an Exception Handling framework deployed you can simply enable “Failed Message Routing” on your Send Ports. When the Send Port creates the error message, your framework will consume and remove it from the Message Box. Alternatively, you can construct a simple Send Port that subscribes to all messages with a Filter of ErrorType.ErrorMessage = “FailedMessage” and handle as needed.

Hope this was helpful!
- D

« Back to Blog main page