How do I restart an opened workflow?

I created a worker object before calling reset workflow execution method. But it did not work. The workflow remains in Running status.

          WorkerFactory factory = WorkerFactory.newInstance(workflowClient);

          Worker worker = factory.newWorker(TASK_QUEUE);

          worker.registerWorkflowImplementationTypes(TripBookingWorkflowImpl.class);
          
          ResetWorkflowExecutionRequest request = ResetWorkflowExecutionRequest.newBuilder().setNamespace("test-nm")
                        .setReason("Testing").setWorkflowExecution(ex).setWorkflowTaskFinishEventId(16).build();
          
          ResetWorkflowExecutionResponse response = service.blockingStub().resetWorkflowExecution(request);

Did you call the factory.start? Did you make sure that the worker process keeps running?

What is the use case? I cannot imagine one that does reset workflow from the main method of the process that hosts the workflow and activity worker.

Hi Maxim. I have set max retry for activity to 3. So in case of failure it got retried 3 times. When i am trying to retry manual using reset method, i am getting error like it has already been retried for maximum time.

Can you help me on how to manually retry now?

We recommend using reset for catastrophic situations. In your case, I would recommend not setting max retries for the activity and let it retry for a long time. It would require no manual intervention if the activity is down for some time.

1 Like

@maxim Hi Maxim,
I want to restart a workflow from the failed task/activity instead of restarting from the beginning.
Is there a way to do that programmatically in JAVA?

Hi @Sumit_Rana
You could use reset for this, see sample here. Just make sure that
the event you are resetting to is of type WorkflowTaskStarted.

Hi @tihomir
My workflow had certain retry policy which was exhausted and workflow went to error state. Now if I restart the workflow it does not restart the failed activity as the retries are over. How can I specify/override new retry policy while restarting?

How are you “restarting” your workflow? Are you using reset feature?

Reset creates a new workflow run and replays your history up to the set WorkflowTaskStarted event, then executes your code from then on.
If you had let’s say history:

1. WorkflowExecutionStarted
2. WorkflowTaskScheduled
3. WorkflowTaskStarted
4. WorkflowTaskCompleted
5. ActivityTaskScheduled
6. ActivityTaskStarted
7. ActivityTaskFailed
...
X. WorkflowExecutionFailed

resetting to event number 3 would create a new run, replay up to that event, and then invoke your activity again that failed in previous run.

I followed the above sample you have provided.

That link I provided has the wrong line in the same file, sorry.
Link to reset method via Java SDK: temporal-java-workshop/S1WFUtils.java at main · tsurdilo/temporal-java-workshop · GitHub

You can also reset via tctl.

Thanks @tihomir I will try this one.

@alex Thanks for adding the functionality to Go SDK client.
Most of the request parameters are self-explanatory.
But I did not know what to set to WorkflowTaskFinishEventId.
There is server-side validation, so it should be >1 and less than current event id.

It seems like 4 (first event id of WorkflowTaskCompleted type event) is working.
Is it correct, or is there any constant defined?
My goal is to restart the workflow from the start.

But I did not know what to set to WorkflowTaskFinishEventId .

I agree this is a little confusing. This is the event id to which you want to reset to. It has have event type WorkflowTaskStarted.

My goal is to restart the workflow from the start.

Reset to the very first WorkflowTaskStarted event in your workflow history.

2 Likes

Sorry to revive this thread, but how can I find the event ID of the first event of type WorkflowTaskStarted? Is there a method I call to view the event history in general (with all of its event IDs and the type of each event?) I am working in Java SDK and cannot find a way to do this.

EDIT: I set it to 4 in my call to setWorkflowTaskFinishEventId() and it started working, but is it always going to be 4?

    ResetWorkflowExecutionRequest request = ResetWorkflowExecutionRequest.newBuilder()
      .setNamespace("default")
      .setReason("Testing")
      .setRequestId(UUID.randomUUID().toString())
      .setWorkflowExecution(execution)
      .setWorkflowTaskFinishEventId(4)
      .build();

Thanks.

You can do something like this:


public static long getFirstWorkflowTaskStartedEventId(String wfId, String wfRunId, String namespace) {
        GetWorkflowExecutionHistoryRequest request =
                GetWorkflowExecutionHistoryRequest.newBuilder()
                        .setNamespace(namespace)
                        .setExecution(WorkflowExecution.newBuilder()
                                .setWorkflowId(wfId)
                                .setRunId(wfRunId)
                                .build())
                        .build();
        History history = service.blockingStub().getWorkflowExecutionHistory(request).getHistory();
        for(HistoryEvent he : history.getEventsList()) {
            if(he.getEventType().equals(EventType.EVENT_TYPE_WORKFLOW_TASK_STARTED)) {
                return he.getEventId();
            }
        }
        // not found
        return -1;
    }

but is it always going to be 4

No, not always. I would rely on finding first in history rather than hard-coding.