Jump steps of a workflow based on external signal

I am using the JAVA SDK. I have a workflow like the following

  1. Send email
  2. Sleep for 5 days
  3. Send email
  4. Sleep for 5 days
  5. Create salesforce case
  6. Sleep for 2 days
  7. Post in slack
  8. Create a JIRA ticket

Based on certain external events in the system, I want to skip all steps and directly jump to Step 7. The workflow could be in any step when the signal is received by the workflow. I.e the workflow could be sleeping as well. How can I achieve this

Put 1-6 into a function and make it return at any of the steps if a signal was received. Something like:

steps1To6(...);
postInSlack(...);
createGira(...);

where

void steps1To6(...) {
    ....
    if (signalReceived) {
        return;
    }
    ...
}

Hmm, yeah this works. Few followups

void steps1To6(…) {

if (signalReceived) {
return;
}

}

1.I will have to add the if statement after every activity execution in this function.
2. And what happens if a signal is received when the workflow has executed one of the sleep steps for X days. If the external signal arrives when the workflow is sleeping, how can I cancel the sleep and jump all the required remaining steps and move to postInSlack, createJIRA. Is there a way to interrupt the sleep when the external signal arrives ?

  1. You can create a wrapper function that encapsulates this behavior.
  2. Don’t use sleep, use Workflow.await.
1 Like

Ah, thanks for the pointer to use Workflow.await and not sleep.

By any chance have you seen DSLs constructed generically to express this pattern. i.e A workflow defined as a sequence of steps and the ability to skip certain steps and continue execution from a step in response to a signal. Trying to see how this could be generalized in a DSL so that developers can just express this in DSL rather than building the same logic multiple times. This seems more like GOTO pattern

I personally would implement this through cancellation. Something like:

  void workflow() {
    if (!signalReceived) {
      CancellationScope scope =
          Workflow.newCancellationScope(
              () -> {
                step1();
                step2();
                step3();
                step4();
                step5();
                step6();
              });
      scope.run();
    }
    step7();
  }

  void signal() {
    signalReceived = true;
    if (scope != null) {
      scope.cancel();
    }
  }

You can encapsulate this logic into a nicer class if needed.

Amazing. Thanks a lot for this idea. This will exactly fit my use case. Will be good to have this in Java ask samples