In computing like in life, not every attempt is successful the first time. A message delivery to a remote application may be impossible for a while. A particular business action may be impossible due to the temporary unavailability of an enterprise resource. The good news is that these adverse conditions may not last: all what is needed is to retry the failed operation until the issue gets resolved.
This approach is well-known in the industry. Just take a look at how emails operate: delivery between SMTP servers is attempted repetitively until it succeeds. Failure is assumed and dealt with. Following the same principles, we’re happy to introduce the Until Successful routing message processor.
Falling back to a different resource is also a valid strategy in case of failure. This is already possible in Mule, thanks to another member of the “Successful” family, namely the First Successful routing message processor.
The Until Successful message processor acts very much like a store-and-forward station: it stores any MuleEvent it receives and tries to process it a configured number of times at the defined retry frequency.
As such the Until Successful message processor is able to retry:
- Dispatching to outbound endpoints, for example when you’re reaching out to a remote web service that may have availability issues,
- Execution of a component method, for example to retry an action on a Spring Bean that may depend on unreliable resources,
- A sub-flow execution, to keep re-executing several actions until they all succeed,
- Any other message processor execution, to allow more complex scenarios.
By default the Until Successful message processor consider only thrown exceptions as indications of failure.
This said, it can also be configured to look at the result coming back from processing a MuleEvent to determine success or failure or more advanced criteria. For example, in the web world, you would use this feature to make the Until Successful message processor consider any non successful HTTP response code as a failure.
Pay attention to what you configure this message processor to execute: if it encapsulates an asynchronous sub-flow or dispatches to an in-only endpoint, it may be impossible to assert success in a systematic manner.
It’s time to take a look at the Until Successful message processor in action! This first example demonstrates how to retry sending to an HTTP-based service until success:
Here are the notable points in the above configuration fragment:
- The Until Successful message processor relies on Mule ObjectStore for persisting the events it processes. In this example, we use an in-memory implementation: a persistent implementation would be required in order to ensure that nothing gets lost in case of a restart or crash.
- It is configured to retry every 10 minutes for an hour. Afterwards, the message will be discarded.
- It interacts synchronously (request-response) with the outbound HTTP endpoint in order to ensure the remote web service correctly accepted the POSTed message (ie. replied a 202 status code).
The following example shows that other flows can be retried the same way:
Notice how the Until Successful message processor has been configured to synchronously acknowledge it has accepted the inbound event for processing by returning the current message correlation ID. Sending to the “signup” VM endpoint will therefore return the correlation ID of the message whose processing by the sub-flow named “signup-flow” will be tried (and retried).
When all else has failed
If message processing keeps failing and the maximum number of retried is exceeded, the default behavior of the Until Successful message processor consists in logging the message details and dropping it.
Should you want to perform a specific action on the discarded message (for example, storing it in a file or database), it is possible to configure a “DLQ endpoint” where dropped messages will be sent to.
The above example shows how a VM endpoint can be used to receive messages that have be discarded.
As a closing note, you’ll realize that using the Until Successful message processor will encourage you to check the availability profile defined in the SLAs of the accessed resources. Indeed, using the values found in the SLAs of the services you depend on will provide you the ideal values for the number of retries or the time between them.