Hi there!
I have a workflow that’s calling an activity which is calling an api. When the api fails the retry will kick in. Once retry has reached the maximumAttempts, it shows a wf execution status as “Failed”.
There is a possibility of a cancel signal to arrive at any point which should mark the workflow as successfully completed or cancelled, ideally, regardless of whether it’s working on an activity or is in a failed state.
When the workflow hasn’t reached the activity call, I can simply return when the signal has arrived but once the activity call is reached, I believe the signal does not get executed until the event loop is done with retrying the activity (possibly for a long time, depending on the retry policy). I also believe that once the workflow is in a Failed status, it won’t be able to process the signal anymore.
Again, a cancel signal should cause the workflow to be marked as successfully complete or cancelled.
What’s the best way to achieve that? Is there a good pattern?
Assuming that a signal can’t be processed if a wf is in a Failed state or until the activity returns a result to the workflow, I’m thinking that I’d have to catch the exceptions of the api in the activity and return a result to the wf that I can interpret via workflow code. Unfortunately for this solution, I’d have to wait and retry via code vs. using temporal retry mechanisms.
let isCancel = false;
export async function setupHandlers(): Promise<void> {
setHandler(signals.cancel, (signal) => {
isCancel = true;
});
}
export async function myWorkflow({myId}: MyWorkflowInput): Promise<unknown> {
await setupHandlers();
let isSuccess = false;
while (!isSuccess && !isCancel) {
const result = await executeMyActivity();
isSuccess = result.isSuccess;
if (isCancel) {
return 'need for activity got cancelled';
}
if (!isSuccess) {
log.info(`activity failed`);
// waiting before making next attempt
await wf.sleep(1000 * 60); // sleep for 60 seconds
// probably throw an ApplicationError at some point to avoid retrying indefinitely.
}
}
return; // successful completion
}
Is there a better way?
Thank you for your thoughts!