TS - Cancelling child workflow terminate the application with exception

Referring to this code here, I am assuming it will be continued as new after one day, but what will happen if we continuously get updates?

Also I am starting new child workflow when I get a signal and inside that child workflow I am executing an activity which needed to run Infinitely, but I am not able to achieve that because all activities has closeTimeout which crashes the activity and eventually crashes the application with exception that Workflow cancelled without any reason, Same happens if user tries to manually cancel the child workflow using child workflow id

P.S. Inside the activity I am invoking an external command which needed to be run on the background for as long as we want it to be.

interface Input {
  /* define your workflow input type here */
}
interface Update {
  /* define your workflow update type here */
}

const MAX_ITERATIONS = 1;

export async function entityWorkflow(
  input: Input,
  isNew = true
): Promise<void> {
  try {
    const pendingUpdates = Array<Update>();
    setHandler(updateSignal, (updateCommand) => {
      pendingUpdates.push(updateCommand);
    });

    if (isNew) {
      await setup(input);
    }

    for (let iteration = 1; iteration <= MAX_ITERATIONS; ++iteration) {
      // Ensure that we don't block the Workflow Execution forever waiting
      // for updates, which means that it will eventually Continue-As-New
      // even if it does not receive updates.
      await condition(() => pendingUpdates.length > 0, '1 day');

      while (pendingUpdates.length) {
        const update = pendingUpdates.shift();
        await runAnActivityOrChildWorkflow(update);
      }
    }
  } catch (err) {
    if (isCancellation(err)) {
      await CancellationScope.nonCancellable(async () => {
        await cleanup();
      });
    }
    throw err;
  }
  await continueAsNew<typeof entityWorkflow>(input, false);
}

Couple of questions here:

  • How to work with infinitely running activities?
  • How to gracefully handle the cancel child workflow without crashing the application.
  • How to handle the event logs warning and initiate continue as new when we are about to reach the event history

Hi,
Can you provide more information?
Which SDK version are you using?
What do you mean by “terminate the application with exception”? I haven’t seen this error in the SDK code, can you show the full message and stack trace and in which context you’re seeing it?

Updates will be processed one by one until they’re all drained. Workflow doesn’t continue as new until processing is finished.
Make sure that you don’t send updates “too frequently” or else your workflow history will grow beyond the allowed limit and will be terminated by Temporal.
You can extend this sample to somewhat mitigate this problem by sending the pending updates over to the next execution when continuing as new.

What’s the use case of having an infinitely long activity? I’m curious…

I think you can avoid the activity failing if you set a very very high start to close timeout (e.g. Number.MAX_VALUE or Number.MAX_SAFE_INTEGER), I’d also suggest setting a heartbeat timeout on that activity, otherwise when your worker goes down Temporal cannot detect that your activity is not executing.

Either use the pattern I suggested above, or if your activity has to run some upstream call on a fixed interval, you can fail the activity after each time it is called and using a properly configured retry policy, Temporal will automatically retry the activity in the next interval.

OTOH, if the interval is long enough (say 10 minutes or longer), you can loop from a workflow and customize the interval with your own code.

Not sure what you’re seeing here, please provide more details

Currently the history size isn’t exposed in the TS SDK so you’d have to estimate how long the history is and determine in your workflow code when to continue as new.

I am using Typescript SDK.
Here is the stack trace I am getting if activity got timed out, it crashes the whole application.

TypeError: Got cancel activity cancel task with no reason
    at E:\Development\worker\node_modules\@temporalio\worker\lib\worker.js:385:39
    at E:\Development\worker\node_modules\@temporalio\worker\lib\tracing.js:65:26
    at NoopContextManager.with (E:\Development\worker\node_modules\@opentelemetry\api\build\src\context\NoopContextManager.js:36:24)
    at ContextAPI.with (E:\Development\worker\node_modules\@opentelemetry\api\build\src\api\context.js:71:54)
    at instrument (E:\Development\worker\node_modules\@temporalio\worker\lib\tracing.js:61:29)
    at E:\Development\worker\node_modules\@temporalio\worker\lib\worker.js:303:55
    at state (E:\Development\worker\node_modules\@temporalio\worker\lib\rxutils.js:8:78)
    at E:\Development\worker\node_modules\rxjs\dist\cjs\internal\operators\mergeScan.js:10:101
    at doInnerSub (E:\Development\worker\node_modules\rxjs\dist\cjs\internal\operators\mergeInternals.js:22:31)
    at outerNext (E:\Development\worker\node_modules\rxjs\dist\cjs\internal\operators\mergeInternals.js:17:70)

I got that,
If parent workflow has N number of child workflow running, then does parent workflow requires continue as new as well or only child workflows requires that.
Also when the parent workflow considers then updates are completely processed in above scenario?

I want to execute another script which runs in the background waiting for certain inputs to process, since it’s a background process, I can’t kill the activity as long as that process is executing, so I need to keep the activity alive.

Thank you, I will try that

Thank you, I will try that.

Already shared the exception above.

Alright, I think we can figure something out.

This was fixed in recent SDK releases, can you verify it doesn’t happen if you upgrade the SDK?