When cancelled the workflow does not complete. It continues to be in the running state

I guess this is due to the await block. Is there better way to do it? Need to make the boolean isWorkflowDone thread safe from multiple access from threads. Please provide your valuable feedback.

public class GenericWorkflowImpl implements GenericWorkflow {
    private boolean isWorkflowDone = false;
    private final RetryOptions retryoptions = RetryOptions.newBuilder()
            .setInitialInterval(Duration.ofSeconds(1))
            .setMaximumInterval(Duration.ofSeconds(100))
            .setBackoffCoefficient(2)
            .setMaximumAttempts(10)
            .build();
    private final ActivityOptions options = ActivityOptions.newBuilder()
            .setStartToCloseTimeout(Duration.ofSeconds(30))
            .setRetryOptions(retryoptions)
            .setCancellationType(ActivityCancellationType.TRY_CANCEL)
            .build();

    private final GenericActivity genericActivity = Workflow.newActivityStub(GenericActivity.class, options);

    @Override
    public void start(final WorkflowType workflowType, final String taskType, final TaskInfo payload) {
        genericActivity.createNewTask(workflowType, taskType, payload);
        Workflow.await(() -> isWorkflowDone);
    }

    @Override
    public void approveChange() {
        genericActivity.approveTaskChange();
        genericActivity.updateTaskStatusChange();
        this.isWorkflowDone = true;
    }

    @Override
    public void rejectChange() {
        CancellationScope scope = Workflow.newCancellationScope(() -> {
            genericActivity.updateTaskStatusChange();
        });
        scope.run();
        scope.cancel();
    }
}

Hi, can you give a little more info on your use case? In your rejectChange signal handler you are invoking and then canceling the updateTaskStatusChange activity that is in the CancellationScope. Would like to understand what you would like to do.

@tihomir The usecase is that the user would be able to either approve or reject a workflow.

  1. If approved. The workflow would be completed successfully.
  2. If rejected. I want it the workflow to be cancelled.
    I tried setting this.isWorkflowDone = true; in reject change which will complete the workflow and also not thread safe.

Is there a better way to approach this usecase? I want the workflow to be cancelled not completed.

Workflow canceling itself doesn’t make sense in Temporal. Cancellation, by definition, is an external request to a workflow from outside.

So if you want your workflow to be canceled, then you want to request cancelation through the client instead of sending rejectChange signal.

@maxim @tihomir Is there a example of sending a cancellation request through the client? Im kindof new to the whole thing.

We don’t have a sample for it currently in the java samples repo but will add.

You could do something like (typed stub)

MyWorkflow workflow =
      client.newWorkflowStub(MyWorkflow.class,"<workflowId>");

WorkflowStub.fromTyped(myWorkflow).cancel();

or untyped

WorkflowStub stub =
        client.newUntypedWorkflowStub("<workflowid>", Optional.empty(), Optional.empty());
stub.cancel();
1 Like

Thanks for the help.