Search code examples
xmlmulesoftanypoint-studioanypoint-platform

Mulesoft sending multiple queries asynchronously and waiting for the response


Need help with speeding up a mule flow.

Right now I have 4 queries that I need to make. The first 3 queries are not dependent upon one another so I want to do the 3 queries async. Once they all 3 finish, I want to pass the results to the 4the query. Right now these api requests are taking between 2-4 seconds(via postman) and I am hoping this will speed things up.

The queries are simple and in english they are,

  1. get a recordTypeId
  2. get a recordTypeId
  3. get account info where pin == request query item
  4. get cases where recordTypeId == recordTypeId's(first 2 queries) and accountLookup == account Id(third query)

the Issue im having is putting the 3 queries in an async block. and waiting for them to finish before making the 4th query.

I tried to use an until-success block but this didn't seem to work.

right now I have the following code

<! -- Goal here is to make the following 3 queries at the same time. -->

<async doc:name="Async" doc:id="4c25219e-d163-4fa2-b8cf-51e13eb020c5">
    <salesforce:query doc:name="get support case record id" doc:id="4c5955f0-484f-4fc1-ad6b-981c367b825e" config-ref="qapartial" targetValue="#[payload[0].Id]" target="supportCaseRecordTypeId">
        <salesforce:salesforce-query><![CDATA[SELECT Id FROM RecordType WHERE SObjectType = 'Case' AND DeveloperName = 'SUPPORT']]></salesforce:salesforce-query>
    </salesforce:query>
                                
    <salesforce:query doc:name="get app support case record type Id" doc:id="c7490429-736e-4fb1-8ec1-c74c2e59e631" config-ref="qapartial" target="appSupportCaseRecordTypeId" targetValue="#[payload[0].Id]">
        <salesforce:salesforce-query><![CDATA[SELECT Id FROM RecordType WHERE SObjectType = 'Case' AND DeveloperName = 'SUPPORT_TICKET_FROM_APP']]></salesforce:salesforce-query>
    </salesforce:query>

    <salesforce:query doc:name="get account Id from pin" doc:id="ccc565b8-88c8-45c5-9b9e-fc474d3da81f" config-ref="qapartial" target="accountId" targetValue="#[payload[0].Id]">
        <salesforce:salesforce-query><![CDATA[SELECT Id, pin__c
       FROM Account
       WHERE pin__c = ':customerPin']]></salesforce:salesforce-query>
        <salesforce:parameters><![CDATA[#[output application/java
            ---
            {
            customerPin : vars.pin
            }]]]></salesforce:parameters>
    </salesforce:query>
</async>


<! -- Goal here is to run this code AFTER the 3 queries finish. -->

<salesforce:query doc:name="get case records" doc:id="f0aed7fb-f47d-4392-b5b8-95993d0bba7e" config-ref="qapartial">
    <salesforce:salesforce-query><![CDATA[SELECT Id FROM Case  WHERE AccountId = ':accountId' AND
     (
        (RecordTypeId = ':appSupportCaseRecordId' AND Origin = 'App') OR 
        (RecordTypeId = ':supoprtCasesRecordId' AND 
                (Origin = 'Email' OR 
                 Origin = 'Phone' OR 
                 Origin = 'Web')) 
      )]]></salesforce:salesforce-query>
                            <salesforce:parameters><![CDATA[#[output application/java
        ---
        {
        accountId : vars.accountId,
        supoprtCasesRecordId : vars.supportCaseRecordTypeId,
        appSupportCaseRecordId : vars.appSupportCaseRecordTypeId
        }]]]>
    </salesforce:parameters>
</salesforce:query>

Solution

  • I suspect there is a confusion on how Async works. The documentation says:

    Because the Async scope is executed in a "fire and forget" manner, the result of the processing within the scope is not available in the main flow.

    That means that you can not use Async to get the results back. Also note that the 3 queries inside the Async scope execute sequentially, one after each other. It doesn't parallelize the steps inside.

    If you want to receive the results you could either:

    1. Use something like a queue, for example a VM queue, to send results to another flow. The query after the Async should be moved to a separate private flow that would be triggered by a VM queue listener, waiting for a VM send from the Async router with the result of the 3 queries.
    2. Alternatively use the Scatter/Gather scope to execute the 3 queries potentially in parallel, then collect the results from the 3 routes for the 4th query.