I’m trying to provide an option to our users that should restart a workflow.
This workflow implements a process during which the user needs to enter various data points in different steps. The inputs trigger asynchronous processes that might take a while. Unfortunately the current reality is that a lot can go wrong in these asynchronous processes. In order to be able to deal with unforeseen errors we would like to provide the nuclear option of “discard everything and just try again from the start” to the user.
First I thought that resetWorkflowExecution might be the way, but then I realised that it replays the history, which I do not want. My goal is that the workflow is in the same state as it was when it was initially started.
My only other idea is to start a new workflow with the same initial input, cancel the current workflow and redirect the user to the new workflow (the workflow id is part of the URL). Is there a better way to do this?
My goal is that the workflow is in the same state as it was when it was initially started.
You could achieve this with reset, by resetting to the first WorkflowTaskScheduled, or WorkflowTaskStarted events in your workflow history. The initial workflow inputs are recorded in the very first WorkflowExecutionStarted event so they would be reapplied on the workflow execution created by reset.
Which SDK are you using? Maybe instead of the “nuclear” option you could send a cancellation client request for the execution which would allow your to handle the it gracefully (and run compensation activities if needed).
Some samples below:
I tried resetting to the first WorkflowTaskStarted Event. But it seemed to me that somehow the signals sent to the original execution are replayed onto the restarted execution, which is not what I want. Maybe I’ll try this out again in a simpler POC.
The “cancellation” option to me was the “nuclear” option, as it requires me to manually cancel the current execution and handle the restarting and everything myself.
Figured out how to do it with the typescript SDK, posting it here for documentation purposes:
import { temporal } from '@temporalio/proto';
const resetWorkflowExecutionRequest = temporal.api.workflowservice.v1.ResetWorkflowExecutionRequest.create({
workflowExecution: {
workflowId: "workflow-id",
runId: "run-id"
},
resetReapplyType: temporal.api.enums.v1.ResetReapplyType.RESET_REAPPLY_TYPE_NONE,
workflowTaskFinishEventId: new Long(3) // The event id to reset to, can be found via connection.workflowService.getWorkflowExecutionHistory
// ...rest of attributes as needed
})
await client.workflowService.resetWorkflowExecution(
resetWorkflowExecutionRequest,
);