Limit workflow-based concurrent executions?

Hi, I am looking for a way to limit the concurrent amount of a type of workflow.
This often is because the executing workflow code must work based on some kind of semaphore.

There is not server side support for this feature. We have plans to add such support in the future, but currently you have to implement it in the application code.

What is the use case? Such limitation is very rarely needed.

Hi Maxim, my workflow uses activities to instrument an external service that can only process 1 task concurrently.

For such a use case, I would use a mutex workflow. The basic idea that for each such resource exists a single workflow execution that invokes that activity. All other workflows send signals to this workflow to request the activity execution. The mutex workflow upon receiving a signal invokes the activity or buffers it until the previous execution is done.

Here is a sample of such a workflow.

Hi maxim,

Thanks for this tip, as it was very helpful!

I have a similar situation, but with an additional constraint: there is a “sequence number” of the tasks sent to the external service, and it is not allowed to send tasks out of order: I need to ensure that a task is not sent to the external service if a task with a higher sequence number has already been sent (I should just discard the lower numbered task).

I tried to implement this with a permanent mutex workflow that remembers the highest sequence number sent and refuses to give out locks for a lower sequence number. The issue is that, because this workflow lives forever, I need to use ContinueAsNew from time to time (passing on the sequence number to the new run), and I found that occasionally when I returned my NewContinueAsNewError there happened to be a signal already queued at that moment, which I think resulted in the signal getting thrown away.

Is there a way to have a workflow that receives signals ContinueAsNew while guaranteeing that no signals are missed?

For anyone who might find this thread on Google and be wondering about my question: see this later thread in which I provided some pared-down example code. The bottom line is that you should drain all open signal channels immediately before returning if you wish to ensure that you did not miss any signals.

1 Like