Synchronizing signal method executions

I’d like to ask if there is a way / pattern of synchronizing signal method invocations.

In our use case, REST controller handles user responses. These are then signalled to a running workflow.

The issue is when a signalmethod would modify how the next signalmethod invocation should be handled (imagine only the first response is accepted, but the response has to be verified against external api called via activity).

For example:

  1. acceptSignal is handled, invoking someActivityMethod -> scheduling someActivityTask1
  2. another acceptSignal is handled -> scheduling someActivityTask2.
  3. someActivityTask1 starts and completes (calling external api and modifying workflow state)
  4. someActivityTask2 starts and completes (calling external api…)

We would ideally want to wait for someActivityTask1 (and any other tasks scheduled in the signal method) to finish before entering the @SignalMethod again, calling the someActivityMethod and scheduling someActivityTask2.

Is this a valid case?
Should we somehow utilize the WorkflowQueue or is there a different pattern for accomplishing this with workflows only, without utilizing some external synchronization?

Thank you

edit: I feel like I might be asking similar thing to what has been answered here: Limit workflow-based concurrent executions? so I will explore the linked repository, although I am already signalling this workflow so this is where I would like to buffer the activity executions.

You cannot delay @SignalMethod invocation. So for your use case buffering the signal data in the workflow field of WorkflowQueue type is the best option. I filed an issue to make the threading of the signal handling method configurable.

Thank you for the answer (and for filing the feature issue).
We will try implementing the signal handling using the WorkflowQueue for now.

I don’t feel confident submitting changes to the documentation as I clearly don’t understand the internals very well but in this case, the section about workflow constraints

Don’t use any synchronization, locks, and other standard Java blocking concurrency-related classes besides those provided by the Workflow class. There is no need in explicit synchronization because multi-threaded code inside a workflow is executed one thread at a time and under a global lock.

was probably the primary source of our confusion when it comes to how the threading works with signals.