Skip to content

Flow and concurrency control

Power Platform’s tools can be used to implement a wide variety of solutions. But if the solution has requirements related to concurrency management, you should stop and think for a moment.

Basically, everything works as expected.

  • If several users use canvas Power Apps to edit the same Dataverse row, the last one to complete the recording wins and rolls over the others’ changes.
  • More than one instance of one cloud flow can be executed at the same time. If the instances update the same rows, the last update remains in effect.

With Power Automate this can be a problem. Cloud flow’s parallel executions can read and write the same records crosswise, so the end result may be completely different than it should be.

Next, we’ll see if something can be done about this.

Flow concurrency control

We have a flow that takes about 15 seconds to complete.

Several instances of the same process can be running at the same time. Usually, there is no problem with this.

But this time this is an issue. We want to prevent parallel executions of a cloud flow. Therefore, only one instance of a flow can be running at the same time.

This can be done easily from the settings of the flow’s trigger.

Turn on the concurrency control and set the number of flows to be run in parallel to 1.

Note! After saving, the setting cannot be reset to its original value (Concurrency Controll = Off).

Now if the flow is triggered several times almost at the same time, only the first request will run. The rest are waiting their turn.

In time, every instance of the flow gets to the run through its automation steps (one at a time, in the order of arrival).

Clever.

Note! This is also one way to try to avoid consuming too much capacity in the 5-minute time window, when requests start to be throttled. You may need to pay attentionto this if a lot of procedures are performed in flows using the same connection.

Flow concurrency control and Power Apps canvas apps

We have successfully prevented parallel execution of flows. Let’s start the same flow from a Power Apps canvas app. We then stay in the application and wait for a return value from the flow.

Set(gblReturnValue, Flowwithconcurrencycontrolontrigger.Run())

Our slightly modified flow looks like this. The trigger has concurrency control turned on.

However, we can’t save the flow anymore. It just throws an error.

Request to XRM API failed with error: 'Message: Flow client error returned with status code ”BadRequest” and details ”{”error”:{”code”:”InvalidFlow”,”message”:”The concurrency configuration of Workflow trigger ' manual' of type 'Request' at line '1' and column '699' is not valid. The concurrency control is not supported when the Workflow contains actions of type 'response' without the operationOptions flag set to 'asynchronous'."}}". Code: 0x80060467 InnerError: '.

Since we have turned on concurrency control, the action that sends a response to Power Apps (Respond to a Power App or flow) should be set to respond asynchronously.

Asynchronous response in cloud flows

What does this mean in practice?

When a flow starts, it does not wait for the execution to end, but immediately returns the information to Power Apps that the request has been accepted (202 Accepted).

In Power Apps, this shows that the execution of the flow appears to have finished, but the return value we stored in the variable is empty!

So we don’t send the return value to our Power Apps, because at the time the message arrives, the flow’s execution is still in progress.

Let’s open the Power Apps Monitor tool where we can see what the flow actually returns to Power Apps. No return value was found in the message. But we see that the status of the message is 202.

In addition, the message contains a location address. It allows you to track the progress of the request.

When the flow run has finished, the final result can be found from the location address.

However, we don’t get the location address to read in Power Apps. Otherwise, we could create a timer that regularly checks from the location address whether Flow’s execution has finished and what the returned value is.

We’ve got to figure out another way.

Implementing your own lock?

Let’s approach the problem from another direction. We will create a flow whose concurrency is not controlled (we can return the end result to Power Apps). This time we will prevent concurrent executions of the flow ourselves – with our own lock.

  • Let’s create a lock table into the Dataverse with one row
  • At the beginning of the flow’s execution, we are in a loop (Do Until) until the value of the row of the lock table is unlocked
  • When the lock is released, its value is set to locked and the actual procedures are performed
  • Finally, the lock is released and the result of the flow is returned to Power Apps

Clever but…

Even if the value of the lock is examined every second, it is possible that several executions will pass through the loop.

Oh no.

Any other ideas?

Something should be invented.

What if we used the Response action instead of Respond to a PowerApp or flow?

Naturally, the Response action should also be set to non-realtime. So, this just gives us the same result.

Is this a limitation of Power Automate? What if we implemented the same process in Azure Logic Apps?

After all, this is the same platform and the same challenge in the background. So we get the same result.

What if we store the location address returned by flow in Dataverse? Power Apps could read it from there and use it to monitor whether the execution is complete and what is its final result.

But… You can’t get a hold of that location address even with the flow.

Of course, we can save the result of the flow in Dataverse itself.

This way we can start the flow in Power Apps and then use a timer to wait until the return value appears in the table we created for this purpose in Dataverse. Of course, a unique key must be passed to the flow as a parameter, with which the final result of the execution in question can be found among the rows of the table.

This seems a bit awkward now.

Solution: child flow

However, the solution is ultimately simple.

A new flow is created, which is called from Power Apps. Its concurrency setting is not touched. This flow does nothing but start the original flow (which is executed one at a time). Finally, the flow returns the value it received from the child flow to Power Apps.

The parent flow ensures the child flow can get the return value for us. It waits patiently until the child flow is completed. Even if there are several of them in the queue.

The flow can be called from Power Apps several times, and they start running immediately.

But the child flow (where the actual work is done) is executed one at a time

The final result returned by our child flow is then returned to Power Apps via the parent flow. Just like we wanted.

Summary

We got off easy in the end. However, the solution has a few limitations imposed by the platform, which are good to be aware of.

Connections

The child flow’s actions cannot normally use the Power Apps user’s own connections. All operations are performed in the flow with predefined connections. This can be a problem in some situations.

Timeout between Power Apps and flow

The connection between Power Apps and Power Automate cloud flows is disconnected if no response has been received within 120 seconds. If the execution of a child flow takes 10 seconds, there can only be 12 executions in the queue. The other child flows will complete, but Power Apps will never know what their final results were.

This can be a significant problem. Our original requirement was that we want to finally tell the Power Apps user the result returned by flow.

Child flow call timeout

If the flow has to wait a long time for its turn to execute a child flow, the action ends up in a timeout and retries.

If the flow has to wait too long (=too many retries), the child flow will not be executed at all, but its call will fail.

At this point, we have also lost the connection between our flow and Power Apps.

If you want to be prepared for this situation, both flows must save their status information about possible errors and the final result in their own table.

If the connection between Power Apps and the flow is timed out, Power Apps can monitor the result of the flow from that table (the result of a successful execution, an error occurred, the flow was not executed at all) and tell the user about it.

And that’s how this got complicated again in the end.

Power Automate

Leave a Reply

Your email address will not be published. Required fields are marked *