diff --git a/docs/develop/dotnet/continue-as-new.mdx b/docs/develop/dotnet/continue-as-new.mdx index 89b7b81a6f..4272bbb045 100644 --- a/docs/develop/dotnet/continue-as-new.mdx +++ b/docs/develop/dotnet/continue-as-new.mdx @@ -2,49 +2,110 @@ id: continue-as-new title: Continue-As-New - .NET SDK sidebar_label: Continue-As-New -description: Learn how to use Continue-As-New with the Temporal .NET SDK to manage Workflow Event Histories, ensuring optimal performance by starting new Executions seamlessly. +description: Learn how to use Temporal's Continue-As-New in .NET to manage large Event Histories by atomically creating new Workflow Executions with the same Workflow Id and fresh parameters. +toc_max_heading_level: 2 keywords: - - sdk - - dotnet - - continue-as-new + - continue-as-new workflow + - restart workflow + - fresh event history + - avoid large event histories + - temporal dotnet continue-as-new tags: - Workflows + - continue-as-new - .Net SDK - Temporal SDKs - - continue-as-new --- -This page describes how to Continue-As-New using the Temporal .NET SDK. +This page answers the following questions for .NET developers: + +- [What is Continue-As-New?](#what) +- [How to Continue-As-New?](#how) +- [When is it right to Continue-as-New?](#when) +- [How to test Continue-as-New?](#how-to-test) -[Continue-As-New](/workflow-execution/continue-as-new) enables a Workflow Execution to close successfully and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is becoming too large. -The Workflow Execution spawned from the use of Continue-As-New has the same Workflow Id, a new Run Id, and a fresh Event History and is passed all the appropriate parameters. +## What is Continue-As-New? {#what} -:::caution +[Continue-As-New](/workflow-execution/continue-as-new) lets a Workflow Execution close successfully and creates a new Workflow Execution. +You can think of it as a checkpoint when your Workflow gets too long or approaches certain scaling limits. -As a precautionary measure, the Workflow Execution's Event History is limited to [51,200 Events](https://github.com/temporalio/temporal/blob/e3496b1c51bfaaae8142b78e4032cc791de8a76f/service/history/configs/config.go#L382) or [50 MB](https://github.com/temporalio/temporal/blob/e3496b1c51bfaaae8142b78e4032cc791de8a76f/service/history/configs/config.go#L380) and will warn you after 10,240 Events or 10 MB. +The new Workflow Execution is in the same [chain](/workflow-execution#workflow-execution-chain); it keeps the same Workflow Id but gets a new Run Id and a fresh Event History. +It also receives your Workflow's usual parameters. -::: +## How to Continue-As-New using the .NET SDK {#how} -To prevent a Workflow Execution Event History from exceeding this limit and failing, use Continue-As-New to start a new Workflow Execution with a fresh Event History. +First, design your Workflow parameters so that you can pass in the "current state" when you Continue-As-New into the next Workflow run. +This state is typically set to `None` for the original caller of the Workflow. -A very large Event History can adversely affect the performance of a Workflow Execution. -For example, in the case of a Workflow Worker failure, the full Event History must be pulled from the Temporal Service and given to another Worker via a Workflow Task. -If the Event history is very large, it may take some time to load it. +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+```csharp +public record Input + { + public State State { get; init; } = new(); + + public bool TestContinueAsNew { get; init; } + } -The Continue-As-New feature enables developers to complete the current Workflow Execution and start a new one atomically. +[WorkflowInit] +public ClusterManagerWorkflow(Input input) -The new Workflow Execution has the same Workflow Id, but a different Run Id, and has its own Event History. +```` +The test hook in the above snippet is covered [below](#how-to-test). -To Continue-As-New in .NET, throw an exception created by `CreateContinueAsNewException()` from inside your Workflow, which will stop the Workflow immediately and Continue-As-New. +Inside your Workflow, throw a [`CreateContinueAsNewException`](https://dotnet.temporal.io/api/Temporalio.Workflows.ContinueAsNewException.html) exception. +This stops the Workflow right away and starts a new one. +
+ + View the source code + {' '} + in the context of the rest of the application code. +
```csharp -throw Workflow.CreateContinueAsNewException((MyWorkflow wf) => wf.RunAsync(myNewParam)); -``` +throw Workflow.CreateContinueAsNewException((ClusterManagerWorkflow wf) => wf.RunAsync(new() +{ + State = CurrentState, + TestContinueAsNew = input.TestContinueAsNew, +})); +```` + +### Considerations for Workflows with Message Handlers {#with-message-handlers} -:::warning Using Continue-as-New and Updates +If you use Updates or Signals, don't call Continue-as-New from the handlers. +Instead, wait for your handlers to finish in your main Workflow before you throw `CreateContinueAsNewException`. +See the [`AllHandlersFinished`](message-passing#wait-for-message-handlers) example for guidance. -- Temporal _does not_ support Continue-as-New functionality within Update handlers. -- Complete all handlers _before_ using Continue-as-New. -- Use Continue-as-New from your main Workflow Definition method, just as you would complete or fail a Workflow Execution. +## When is it right to Continue-as-New using the .NET SDK? {#when} -::: +Use Continue-as-New when your Workflow might hit [Event History Limits](/workflow-execution/event#event-history). + +Temporal tracks your Workflow's progress against these limits to let you know when you should Continue-as-New. +Call `Workflow.ContinueAsNewSuggested` to check if it's time. + +## How to test Continue-as-New using the .NET SDK {#how-to-test} + +Testing Workflows that naturally Continue-as-New may be time-consuming and resource-intensive. +Instead, add a test hook to check your Workflow's Continue-as-New behavior faster in automated tests. + +For example, when `TestContinueAsNew == true`, this sample creates a test-only variable called `maxHistoryLength` and sets it to a small value. +A helper variable in the Workflow checks it each time it considers using Continue-as-New: + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```csharp +private bool ShouldContinueAsNew => + // Don't continue as new while update running + Workflow.AllHandlersFinished && + // Continue if suggested or, for ease of testing, max history reached + (Workflow.ContinueAsNewSuggested || Workflow.CurrentHistoryLength > maxHistoryLength); +``` diff --git a/docs/develop/java/continue-as-new.mdx b/docs/develop/java/continue-as-new.mdx index 04f7e54cc0..5a0bab6520 100644 --- a/docs/develop/java/continue-as-new.mdx +++ b/docs/develop/java/continue-as-new.mdx @@ -2,58 +2,110 @@ id: continue-as-new title: Continue-As-New - Java SDK sidebar_label: Continue-As-New -toc_max_heading_level: 4 +description: Learn how to use Temporal's Continue-As-New in Java to manage large Event Histories by atomically creating new Workflow Executions with the same Workflow Id and fresh parameters. +toc_max_heading_level: 2 keywords: - - continue-as-new + - continue-as-new workflow + - restart workflow + - fresh event history + - avoid large event histories + - temporal java continue-as-new tags: - Workflows - continue-as-new - Java SDK - Temporal SDKs -description: Learn how to use Continue-As-New with the Java SDK to manage Workflow Executions efficiently in Temporal, ensuring optimal Event History management and flexible Workflow transitions. --- -This page shows how to Continue-As-New using the Java SDK. +This page answers the following questions for Java developers: -[Continue-As-New](/workflow-execution/continue-as-new) enables a Workflow Execution to close successfully and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is becoming too large. -The Workflow Execution spawned from the use of Continue-As-New has the same Workflow Id, a new Run Id, and a fresh Event History and is passed all the appropriate parameters. +- [What is Continue-As-New?](#what) +- [How to Continue-As-New?](#how) +- [When is it right to Continue-as-New?](#when) +- [How to test Continue-as-New?](#how-to-test) -Temporal SDK allows you to use [Continue-As-New](/workflow-execution/continue-as-new) in various ways. +## What is Continue-As-New? {#what} -To continue execution of the same Workflow that is currently running, use: +[Continue-As-New](/workflow-execution/continue-as-new) lets a Workflow Execution close successfully and creates a new Workflow Execution. +You can think of it as a checkpoint when your Workflow gets too long or approaches certain scaling limits. -```java -Workflow.continueAsNew(input1, ...); -``` +The new Workflow Execution is in the same [chain](/workflow-execution#workflow-execution-chain); it keeps the same Workflow Id but gets a new Run Id and a fresh Event History. +It also receives your Workflow's usual parameters. + +## How to Continue-As-New using the Java SDK {#how} -To continue execution of a currently running Workflow as a completely different Workflow Type, use `Workflow.newContinueAsNewStub()`. -For example, in a Workflow class called `YourWorkflow`, we can create a Workflow stub with a different type, and call its Workflow method to continue execution as that type: +First, design your Workflow parameters so that you can pass in the "current state" when you Continue-As-New into the next Workflow run. +This state is typically set to `None` for the original caller of the Workflow. +
+ + View the source code + {' '} + in the context of the rest of the application code. +
```java -MyOtherWorkflow continueAsNew = Workflow.newContinueAsNewStub(MyOtherWorkflow.class); -coninueAsNew.greet(input); -``` +class ClusterManagerInput { + private final Optional state; + private final boolean testContinueAsNew; +} + +@WorkflowMethod +ClusterManagerResult run(ClusterManagerInput input); + +```` +The test hook in the above snippet is covered [below](#how-to-test). -To provide `ContinueAsNewOptions` options in `Workflow.newContinueAsNewStub()` use: +Inside your Workflow, call the [`continueAsNew()`](https://javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/workflow/Workflow.html#continueAsNew(io.temporal.workflow.ContinueAsNewOptions,java.lang.Object...)) function with the same type. +This stops the Workflow right away and starts a new one. +
+ + View the source code + {' '} + in the context of the rest of the application code. +
```java -ContinueAsNewOptions options = ContinueAsNewOptions.newBuilder() - .setTaskQueue("newTaskQueueName") - .build(); +Workflow.continueAsNew( + new ClusterManagerInput(Optional.of(state), input.isTestContinueAsNew())); +```` -MyOtherWorkflow continueAsNew = Workflow.newContinueAsNewStub(MyOtherWorkflow.class, options); -// ... -continueAsNew.greet(input); -``` +### Considerations for Workflows with Message Handlers {#with-message-handlers} + +If you use Updates or Signals, don't call Continue-as-New from the handlers. +Instead, wait for your handlers to finish in your main Workflow before you run `continueAsNew`. + +## When is it right to Continue-as-New using the Java SDK? {#when} + +Use Continue-as-New when your Workflow might hit [Event History Limits](/workflow-execution/event#event-history). -Providing these options allows you to continue Workflow Execution as a new Workflow run, with a different Workflow Type, and on a different Task Queue. +Temporal tracks your Workflow's progress against these limits to let you know when you should Continue-as-New. +Call `Workflow.getInfo().isContinueAsNewSuggested()` to check if it's time. -Java Workflow reference: [https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/workflow/package-summary.html](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/workflow/package-summary.html) +## How to test Continue-as-New using the Java SDK {#how-to-test} -:::warning Using Continue-as-New and Updates +Testing Workflows that naturally Continue-as-New may be time-consuming and resource-intensive. +Instead, add a test hook to check your Workflow's Continue-as-New behavior faster in automated tests. -- Temporal _does not_ support Continue-as-New functionality within Update handlers. -- Complete all handlers _before_ using Continue-as-New. -- Use Continue-as-New from your main Workflow Definition method, just as you would complete or fail a Workflow Execution. +For example, when `testContinueAsNew == true`, this sample creates a test-only variable called `maxHistoryLength` and sets it to a small value. +A helper method in the Workflow checks it each time it considers using Continue-as-New: -::: +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```java +private boolean shouldContinueAsNew() { + if (Workflow.getInfo().isContinueAsNewSuggested()) { + return true; + } + // This is just for ease-of-testing. In production, we trust temporal to tell us when to + // continue as new. + if (maxHistoryLength > 0 && Workflow.getInfo().getHistoryLength() > maxHistoryLength) { + return true; + } + return false; +} +``` diff --git a/docs/develop/php/continue-as-new.mdx b/docs/develop/php/continue-as-new.mdx index d20c6b0f88..a7a33aa882 100644 --- a/docs/develop/php/continue-as-new.mdx +++ b/docs/develop/php/continue-as-new.mdx @@ -2,50 +2,121 @@ id: continue-as-new title: Continue-As-New - PHP SDK sidebar_label: Continue-As-New -slug: /develop/php/continue-as-new +description: Learn how to use Temporal's Continue-As-New in PHP to manage large Event Histories by atomically creating new Workflow Executions with the same Workflow Id and fresh parameters. toc_max_heading_level: 2 keywords: - - continue-as-new + - continue-as-new workflow + - restart workflow + - fresh event history + - avoid large event histories + - temporal php continue-as-new tags: - Workflows - continue-as-new - PHP SDK - Temporal SDKs -description: Learn how to use Continue-As-New to manage large Event Histories in Workflow Execution by creating a new execution with the same Workflow Id but a fresh Event History. --- -## How to Continue-As-New {#continue-as-new} +This page answers the following questions for PHP developers: + +- [What is Continue-As-New?](#what) +- [How to Continue-As-New?](#how) +- [When is it right to Continue-as-New?](#when) +- [How to test Continue-as-New?](#how-to-test) -[Continue-As-New](/workflow-execution/continue-as-new) enables a Workflow Execution to close successfully and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is becoming too large. -The Workflow Execution spawned from the use of Continue-As-New has the same Workflow Id, a new Run Id, and a fresh Event History and is passed all the appropriate parameters. +## What is Continue-As-New? {#what} -Workflows that need to rerun periodically could naively be implemented as a big **while** loop with a sleep where the entire logic of the Workflow is inside the body of the **while** loop. -The problem with this approach is that the history for that Workflow will keep growing to a point where it reaches the maximum size enforced by the service. +[Continue-As-New](/workflow-execution/continue-as-new) lets a Workflow Execution close successfully and creates a new Workflow Execution. +You can think of it as a checkpoint when your Workflow gets too long or approaches certain scaling limits. -**ContinueAsNew** is the low level construct that enables implementing such Workflows without the risk of failures down the road. -The operation atomically completes the current execution and starts a new execution of the Workflow with the same **Workflow Id**. -The new execution will not carry over any history from the old execution. +The new Workflow Execution is in the same [chain](/workflow-execution#workflow-execution-chain); it keeps the same Workflow Id but gets a new Run Id and a fresh Event History. +It also receives your Workflow's usual parameters. -To trigger this behavior, use `Workflow::continueAsNew` or `Workflow::newContinueAsNewStub` method: +## How to Continue-As-New using the PHP SDK {#how} +First, design your Workflow parameters so that you can pass in the "current state" when you Continue-As-New into the next Workflow run. +This state is typically set to `None` for the original caller of the Workflow. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
```php +final class ClusterManagerInput { + public function __construct( + public ?ClusterManagerState $state = null, + public bool $testContinueAsNew = false, + ) {} +} + +#[Workflow\WorkflowInterface] +interface MessageHandlerWorkflowInterface +{ #[Workflow\WorkflowMethod] -public function periodic(string $name, int $value = 0) +public function run(ClusterManagerInput $input); +} + +```` +The test hook in the above snippet is covered [below](#how-to-test). + +Inside your Workflow, call the [`continueAsNew()`](https://php.temporal.io/classes/Temporal-Workflow.html#method_continueAsNew) function with the same type. +This stops the Workflow right away and starts a new one. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+```php +Workflow::continueAsNew( + Workflow::getInfo()->type->name, + [new ClusterManagerInput($this->state, $input->testContinueAsNew)], +); +```` + +### Considerations for Workflows with Message Handlers {#with-message-handlers} + +If you use Updates or Signals, don't call Continue-as-New from the handlers. +Instead, wait for your handlers to finish in your main Workflow before you run `continueAsNew`. +See the [`allHandlersFinished`](message-passing#wait-for-message-handlers) example for guidance. + +## When is it right to Continue-as-New using the PHP SDK? {#when} + +Use Continue-as-New when your Workflow might hit [Event History Limits](/workflow-execution/event#event-history). + +Temporal tracks your Workflow's progress against these limits to let you know when you should Continue-as-New. +Call `Workflow::getInfo()->shouldContinueAsNew` to check if it's time. + +## How to test Continue-as-New using the PHP SDK {#how-to-test} + +Testing Workflows that naturally Continue-as-New may be time-consuming and resource-intensive. +Instead, add a test hook to check your Workflow's Continue-as-New behavior faster in automated tests. + +For example, when `testContinueAsNew == true`, this sample creates a test-only variable called `$this->maxHistoryLength` and sets it to a small value. +A helper method in the Workflow checks it each time it considers using Continue-as-New: + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+ +```php +private function shouldContinueAsNew(): bool { - for ($i = 0; $i < 100; $i++) { - // do something - $value++; + if (Workflow::getInfo()->shouldContinueAsNew) { + return true; + } + + // This is just for ease-of-testing. In production, we trust temporal to tell us when to continue as new. + if ($this->maxHistoryLength !== null && Workflow::getInfo()->historyLength > $this->maxHistoryLength) { + return true; } - // maintain $value counter between runs - return Workflow::newContinueAsNewStub(self::class)->periodic($name, $value); + return false; } ``` - -:::warning Using Continue-as-New and Updates - -- Temporal _does not_ support Continue-as-New functionality within Update handlers. -- Complete all handlers _before_ using Continue-as-New. -- Use Continue-as-New from your main Workflow Definition method, just as you would complete or fail a Workflow Execution. - -::: diff --git a/docs/develop/typescript/continue-as-new.mdx b/docs/develop/typescript/continue-as-new.mdx index 4c5a3e25c7..20e5ebd857 100644 --- a/docs/develop/typescript/continue-as-new.mdx +++ b/docs/develop/typescript/continue-as-new.mdx @@ -1,48 +1,80 @@ --- id: continue-as-new -title: Continue-As-New - TypeScript SDK +title: Continue-As-New - Typescript SDK sidebar_label: Continue-As-New +description: Learn how to use Temporal's Continue-As-New in Typescript to manage large Event Histories by atomically creating new Workflow Executions with the same Workflow Id and fresh parameters. toc_max_heading_level: 2 keywords: - - continue-as-new + - continue-as-new workflow + - restart workflow + - fresh event history + - avoid large event histories + - temporal typescript continue-as-new tags: - Workflows - continue-as-new - - TypeScript SDK + - Typescript SDK - Temporal SDKs -description: Continue-As-New helps manage large Event Histories by initiating a new Workflow Execution with the same Workflow Id and fresh parameters, ensuring efficient Workflow management. --- -[Continue-As-New](/workflow-execution/continue-as-new) enables a Workflow Execution to close successfully and create a new Workflow Execution in a single atomic operation if the number of Events in the Event History is becoming too large. -The Workflow Execution spawned from the use of Continue-As-New has the same Workflow Id, a new Run Id, and a fresh Event History and is passed all the appropriate parameters. +This page answers the following questions for Typescript developers: + +- [What is Continue-As-New?](#what) +- [How to Continue-As-New?](#how) +- [When is it right to Continue-as-New?](#when) +- [How to test Continue-as-New?](#how-to-test) -To cause a Workflow Execution to [Continue-As-New](/workflow-execution/continue-as-new), the Workflow function should return the result of the [`continueAsNew`](https://typescript.temporal.io/api/namespaces/workflow#continueasnew). +## What is Continue-As-New? {#what} - +[Continue-As-New](/workflow-execution/continue-as-new) lets a Workflow Execution close successfully and creates a new Workflow Execution. +You can think of it as a checkpoint when your Workflow gets too long or approaches certain scaling limits. -[continue-as-new/src/workflows.ts](https://github.com/temporalio/samples-typescript/blob/main/continue-as-new/src/workflows.ts) +The new Workflow Execution is in the same [chain](/workflow-execution#workflow-execution-chain); it keeps the same Workflow Id but gets a new Run Id and a fresh Event History. +It also receives your Workflow's usual parameters. -```ts -import { continueAsNew, log, sleep } from '@temporalio/workflow'; +## How to Continue-As-New using the Typescropt SDK {#how} -export async function loopingWorkflow(iteration = 0): Promise { - if (iteration === 10) { - return; - } - log.info('Running Workflow iteration', { iteration }); - await sleep(1000); - // Must match the arguments expected by `loopingWorkflow` - await continueAsNew(iteration + 1); - // Unreachable code, continueAsNew is like `process.exit` and will stop execution once called. +First, design your Workflow parameters so that you can pass in the "current state" when you Continue-As-New into the next Workflow run. +This state is typically set to `None` for the original caller of the Workflow. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+```typescript +export interface ClusterManagerInput { + state?: ClusterManagerState; } -``` - +export async function clusterManagerWorkflow(input: ClusterManagerInput = {}): Promise { + +```` +The test hook in the above snippet is covered [below](#how-to-test). + +Inside your Workflow, call the [`ContinueAsNew()`](https://typescript.temporal.io/api/classes/workflow.ContinueAsNew) function with the same type. +This stops the Workflow right away and starts a new one. + +
+ + View the source code + {' '} + in the context of the rest of the application code. +
+```typescript +return await wf.continueAsNew({ state: manager.getState() }); +```` + +### Considerations for Workflows with Message Handlers {#with-message-handlers} + +If you use Updates or Signals, don't call Continue-as-New from the handlers. +Instead, wait for your handlers to finish in your main Workflow before you run `ContinueAsNew`. +See the [`allHandlersFinished`](message-passing#wait-for-message-handlers) example for guidance. -:::warning Using Continue-as-New and Updates +## When is it right to Continue-as-New using the Typescript SDK? {#when} -- Temporal _does not_ support Continue-as-New functionality within Update handlers. -- [Complete all handlers](/develop/typescript/message-passing#wait-for-message-handlers) _before_ using Continue-as-New. -- Use Continue-as-New from your main Workflow Definition method, just as you would complete or fail a Workflow Execution. +Use Continue-as-New when your Workflow might hit [Event History Limits](/workflow-execution/event#event-history). -::: +Temporal tracks your Workflow's progress against these limits to let you know when you should Continue-as-New. +Call `wf.workflowInfo().continueAsNewSuggested` to check if it's time.