Contact Free trial Login

Parallel For Each Scope

This component is not available in the Anypoint Studio Mule Palette. You are able to configure and use the Parallel For Each scope by manually modifying the XML configuration.

The Parallel For Each scope splits a collection and parallel processes each part of the collection with the components within the scope (subject to any limitation in concurrency that has been configured). The output is a collection with the result of each route. After all messages are processed, the results are aggregated before continuing within the flow in the same order they were in prior to the split.

Configuration

The Parallel For Each scope can be configured through the following fields:

Child element Description

Collection (collection)

Specifies the expression that defines the collection of parts to be processed in parallel. By default, it uses the incoming payload.

Attribute Description

Collection Expression (collection)

An expression that returns a collection. By default, the payload is taken as the collection to split.

Timeout (timeout)

Specifies the timeout for each parallel route. By default, there is no timeout.

Max Concurrency (maxConcurrency)

Specifies the maximum level of parallelism for the router to use. By default, all routes run in parallel.

Target Variable (target)

Specifies a variable to use for storing the processed payload. By default, the output is saved in the flow’s payload.

Target Value (targetValue)

Specifies an expression to evaluate against the operation’s output value. The outcome of this expression is stored in the target variable. By default, this is the same as the operation’s output value.

Example

This XML example adds to every element in the collection the string "-result":

<parallel-foreach collection="#[['apple', 'banana', 'orange']]">
    <set-payload value="#[payload ++ '-result']"/>
</parallel-foreach>

Every execution of the Parallel ForEach scope will start with the same variables and values as before the execution of the block. New variables or modifications of already existing ones while processing one element will not be visible while processing another element. All of those variable changes will not be avaiable outside the Parallel ForEach scope. In other words, the set of variables (and their values) after the execution of the Parallel ForEach Scope will remain the same as before the execution of it.

<set-variable variableName="var1" value="var1"/>
<set-variable variableName="var2" value="var2"/>
<parallel-foreach collection="#[['apple', 'banana', 'orange']"]>
    <choice>
        <when expression="#[payload == 'apple']">
            <set-variable variableName="var2" value="newValue"/>
            <set-variable variableName="var3" value="appleVal"/>
        </when>
        <when expression="#[payload == 'banana']">
            <set-variable variableName="var3" value="bananaVal"/>
        </when>
        <otherwise>
            <set-variable variableName="var3" value="otherVal"/>
            <set-variable variableName="var4" value="val4"/>
        </otherwise>
    </choice>
</parallel-foreach>

After aggregation, the variables are:

{var1: "var1", var2: "var2"}

None of the modifications are registered, including the creation of new variables.

Error Handling

Every route is processed in parallel. So, when an error is thrown in one route, Parallel For Each continues to process each route and then invokes the Error Handler with the aggregation of the results and errors of all the routes, for example:

<parallel-foreach collection="#['banana', 'apple']">
    <choice>
        <when expression="#[payload == 'banana']">
            <!-- Processor that throws error -->
        </when>
        <otherwise>
            <set-payload value="#[payload ++ '-result']"/>
        </otherwise>
    </choice>
</parallel-foreach>
<error-handler>
    <on-error-continue type="COMPOSITE_ROUTING">
        <!-- This will have the error thrown by the above processor -->
        <logger message="#[error.errorMessage.payload.failures['0']]"/>
        <!-- This will be a null value -->
        <logger message="#[error.errorMessage.payload.failures['1']]"/>
        <!-- This will be a null value -->
        <logger message="#[error.errorMessage.payload.results['0']]"/>
        <!-- This will have the result of this (correctly executed) route -->
        <logger message="#[error.errorMessage.payload.results['1']]"/>
    </on-error-continue>
</error-handler>

Throws

  • MULE:COMPOSITE_ROUTING

Differences between For Each and Parallel For Each Scopes

Both For Each and Parallel For Each split the defined collection, and the components within the scope process each element in the collection. Also, in both cases, each route runs with the same initial context. The difference between these two scopes are:

  • For Each works sequentially, while the Parallel For Each processes in parallel. This difference affects error handling:

    Because of the processing differences, the execution of For Each execution is interrupted when an error is raised (and the Error Handler is invoked), while Parallel For Each processes every route before invoking the Error Handler with a MULE:COMPOSITE_ROUTE error type.

  • For Each does not modify the payload, while the Parallel For Each outputs a collection of the output messages from each iteration.

We use cookies to make interactions with our websites and services easy and meaningful, to better understand how they are used and to tailor advertising. You can read more and make your cookie choices here. By continuing to use this site you are giving us your consent to do this.