For your application to benefit from persistent queuing, implement reliability patterns in your application code, separating individual XA transactions from VM transports. See Reliability Patterns for more information.
The reliable acquisition flow reliably delivers a message from an inbound HTTP connector to an outbound VM endpoint. If the reliable acquisition flow cannot put the message into the VM queue, it ensures that the message is not lost by returning an "unsuccessful request" response to the client so that the client can retry the request.
The application logic flow delivers the message from an inbound VM endpoint to the business logic processing in your application. This flow represents one transaction. (Your business logic may involve several other transactions, not shown.)
In between these two flows, a persistent VM queue holds the messages committed by the reliable acquisition flow until they are ready for processing by the application logic flow. In case of a processing error within the transaction or in case of a transaction timeout (the time allotted for the transaction is exceeded), Mule triggers a rollback. This rollback erases any partial processing that has occurred on the message and places the message back on the queue. If your Mule instance experiences an outage and is unable to explicitly roll back a transaction, the transaction automatically rolls back once the time allotted for the transaction is exceeded. The allotted time is determined by the timeout attribute of the transaction element. You can configure the timeout yourself, or accept the default.
It is helpful to think of each transaction in terms of three steps:
-
Begin. Mule kicks off the processing of all subcomponents within the transaction.
-
Commit. Mule sends the result of the completed transaction on to the next step. (For XA transactions, the commit step has two phases: a commit-request phase and a commit phase. During the commit-request phase, Mule coordinates the results of the multiple resources within the scope of the transaction and confirms that all processing executed successfully and is ready to commit. The commit phase then calls each resource to commit its processing.)
-
Rollback. If an error occurs in either the Begin or Commit steps, Mule rolls back the operations within the transaction so that no one part results in partial completion.
The following code snippet provides an example of an application set up in a reliability pattern using VM transports for queue persistence on CloudHub.
<mule xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/jbossts http://www.mulesoft.org/schema/mule/jbossts/current/mule-jbossts.xsd">
<vm:connector name="vmConnector" doc:name="VM">
</vm:connector>
<http:listener-config name="listener-config" host="..." port="..."/>
<!-- This is the reliable acquisition flow in the reliability pattern. -->
<flow name="reliable-data-acquisition" doc:name="reliable-data-acquisition">
<http:listener config-ref="listener-config" path="/" doc:name="HTTP Connector"/>
<expression-filter expression="#[message.inboundProperties.'http.request.path' != '/favicon.ico']" nullReturnsTrue="true" doc:name="Expression"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="input" connector-ref="vmConnector" doc:name="VM"/>
</flow>
<!-- This is the application logic flow in the reliability pattern.
It is a wrapper around a subflow, "business-logic-processing".
-->
<flow name="main-flow" doc:name="main-flow">
<vm:inbound-endpoint exchange-pattern="one-way" path="input" connector-ref="vmConnector" doc:name="VM">
<xa-transaction action="ALWAYS_BEGIN" timeout="30000"/>
</vm:inbound-endpoint>
<flow-ref name="business-logic-processing" doc:name="Flow Reference"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="output" connector-ref="vmConnector" doc:name="VM">
</flow>
<!--
This subflow is where the actual business logic is performed.
-->
<sub-flow name="business-logic-processing" doc:name="business-logic-processing">
....
</sub-flow>
</mule>
Differences Between Hybrid VM Queues and CloudHub VM Queues
The following table describes key differences between hybrid VM queues and CloudHub VM queues.
| VM Queues in On-Premises Applications |
VM Queues in Applications deployed to CloudHub |
You can configure the maximum number of outstanding messages using the queue-profile element.
|
There is no limit to the number of outstanding messages in CloudHub. Even if you have a queue-profile element coded in your application with a maximum number of outstanding messages, CloudHub allows unlimited outstanding messages if you deploy the application to CloudHub with the Persistent Queues checkbox checked.
|
You can toggle the persistence of the queue using the queue-profile element.
|
The persistence of your queue is managed using the Persistent Queues checkbox in the Advanced Details section of the deployment dialog. Even if you have a queue-profile element coded in your application, CloudHub overrides these settings when you deploy the application to CloudHub with the Persistent Queues checkbox checked.
|
You can define a queue store for your VM queue to use.
|
CloudHub manages the queue store for you, so there is no need to define a queue store.
|
Transaction commits and rollbacks for XA transactions operate according to the two-phase commit algorithm.
|
In CloudHub, there is an important exception to the way the two-phase commit algorithm works for XA transactions when a message is being added to a queue. See the known issue described below for details. Note: when CloudHub consumes messages from a persistent queue, this exception to the two-phase commit algorithm does not apply.
|