Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 29 additions & 29 deletions docs/develop/dotnet/workflows/basics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
id: basics
title: Workflow basics - .NET SDK
sidebar_label: Workflow basics
description: This section explains Workflow basics with the .NET SDK
description: Develop a basic Workflow with the Temporal .NET SDK. Define Workflow parameters, return values, and a custom Workflow Type.
toc_max_heading_level: 4
tags:
- .NET SDK
- Temporal SDKs
---

## Develop a Workflow {/* #develop-workflow */}
## Develop a basic Workflow {/* #develop-workflows */}

Workflows are the fundamental unit of a Temporal Application, and it all starts with the development of a [Workflow Definition](/workflow-definition).

Expand Down Expand Up @@ -40,7 +40,31 @@ Temporal Workflows may have any number of custom parameters.
However, we strongly recommend that objects are used as parameters, so that the object's individual fields may be altered without breaking the signature of the Workflow.
All Workflow Definition parameters must be serializable.

### Use Workflow constructors
## Customize Workflow Type {/* #workflow-type */}

Workflows have a Type that are referred to as the Workflow name.

The following examples demonstrate how to set a custom name for your Workflow Type.

You can customize the Workflow name with a custom name in the attribute. For example, `[Workflow("my-workflow-name")]`. If the name parameter is not specified, the Workflow name defaults to the unqualified class name.

```csharp
using Temporalio.Workflows;

[Workflow("MyDifferentWorkflowName")]
public class MyWorkflow
{
public async Task<string> RunAsync(string name)
{
var param = MyActivityParams("Hello", name);
return await Workflow.ExecuteActivityAsync(
(MyActivities a) => a.MyActivity(param),
new() { StartToCloseTimeout = TimeSpan.FromMinutes(5) });
}
}
```

## Use Workflow constructors

Workflow constructors are useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/handling-messages#workflow-initializers). Normally, your Workflows constructor won't have any parameters. The `[WorkflowInit]` attribute gives message handlers access to Workflow input. When you use the `[WorkflowInit]` attribute on your constructor, you give the constructor the same Workflow parameters as your `[WorkflowRun]` method.

Expand Down Expand Up @@ -155,7 +179,7 @@ If your goal is to always take action when something new is happening, check tha
is false instead. That is false during read-only operations like Queries and Update validators. This is what the SDK's
built-in logger and tracing interceptors use internally.

### .NET Task Determinism
## .NET Task Determinism

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Temporal.Headings> reported by reviewdog 🐶
'.NET Task Determinism' should use sentence-style capitalization.


Some calls in .NET do unsuspecting non-deterministic things and are easy to accidentally use.
This is especially true with `Task`s.
Expand Down Expand Up @@ -191,7 +215,7 @@ In the near future for modern .NET versions we hope to use the
[new `TimeProvider` API](https://github.com/dotnet/runtime/issues/36617) which will allow us to control current time and
timers.

### Workflow .editorconfig
## Workflow .editorconfig

Since Workflow code follows some different logic rules than regular C# code, there are some common analyzer rules that developers may want to disable.
To ensure these are only disabled for Workflows, current recommendation is to use the `.workflow.cs` extension for files containing Workflows.
Expand Down Expand Up @@ -239,27 +263,3 @@ dotnet_diagnostic.CS1998.severity = none
# Don't avoid, but rather encourage things using TaskScheduler.Current in workflows
dotnet_diagnostic.VSTHRD105.severity = none
```

### Customize Workflow Type {/* #workflow-type */}

Workflows have a Type that are referred to as the Workflow name.

The following examples demonstrate how to set a custom name for your Workflow Type.

You can customize the Workflow name with a custom name in the attribute. For example, `[Workflow("my-workflow-name")]`. If the name parameter is not specified, the Workflow name defaults to the unqualified class name.

```csharp
using Temporalio.Workflows;

[Workflow("MyDifferentWorkflowName")]
public class MyWorkflow
{
public async Task<string> RunAsync(string name)
{
var param = MyActivityParams("Hello", name);
return await Workflow.ExecuteActivityAsync(
(MyActivities a) => a.MyActivity(param),
new() { StartToCloseTimeout = TimeSpan.FromMinutes(5) });
}
}
```
2 changes: 1 addition & 1 deletion docs/develop/go/client/temporal-client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ In the examples below, all Workflow Executions are started using a Temporal Clie
within another Workflow Execution, use either the [Child Workflow](/develop/go/workflows/child-workflows) or External Workflow
APIs.

See the [Customize Workflow Type](/develop/go/workflows/basics#customize-workflow-type) section to see how to customize
See the [Customize Workflow Type](/develop/go/workflows/basics#workflow-type) section to see how to customize
the name of the Workflow Type.

A request to spawn a Workflow Execution causes the Temporal Service to create the first Event
Expand Down
20 changes: 10 additions & 10 deletions docs/develop/go/workflows/basics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
id: basics
title: Workflow basics - Go SDK
sidebar_label: Workflow basics
description: This section explains Workflow basics with the Go SDK
description: Develop a basic Workflow with the Temporal Go SDK. Define Workflow parameters, return values, and a custom Workflow Type.
toc_max_heading_level: 4
tags:
- Go SDK
- Temporal SDKs
---

## How to develop a basic Workflow {/* #develop-workflows */}
## Develop a basic Workflow {/* #develop-workflows */}

Workflows are the fundamental unit of a Temporal Application, and it all starts with the development of a [Workflow Definition](/workflow-definition).

Expand All @@ -30,7 +30,7 @@ func YourSimpleWorkflowDefinition(ctx workflow.Context) error {
}
```

### How to define Workflow parameters {/* #workflow-parameters */}
## Define Workflow parameters {/* #workflow-parameters */}

Temporal Workflows may have any number of custom parameters.
However, we strongly recommend that objects are used as parameters, so that the object's individual fields may be altered without breaking the signature of the Workflow.
Expand Down Expand Up @@ -86,7 +86,7 @@ func YourWorkflowDefinition(ctx workflow.Context, param YourWorkflowParam) (*You
}
```

### How to define Workflow return parameters {/* #workflow-return-values */}
## Define Workflow return values {/* #workflow-return-values */}

Workflow return values must also be serializable.
Returning results, returning errors, or throwing exceptions is fairly idiomatic in each language that is supported.
Expand Down Expand Up @@ -142,7 +142,7 @@ func YourWorkflowDefinition(ctx workflow.Context, param YourWorkflowParam) (*You
}
```

### How to customize Workflow Type in Go {/* #customize-workflow-type */}
## Customize Workflow Type {/* #workflow-type */}

In Go, by default, the Workflow Type name is the same as the function name.

Expand Down Expand Up @@ -196,7 +196,7 @@ func main() {
}
```

### How to develop Workflow logic {/* #workflow-logic-requirements */}
## Workflow logic requirements {/* #workflow-logic-requirements */}

Workflow logic is constrained by [deterministic execution requirements](/workflow-definition#deterministic-constraints). Each Temporal SDK provides a set of APIs that can be used inside your Workflow to interact with application code outside the Workflow.

Expand All @@ -221,7 +221,7 @@ The Temporal Go SDK has APIs to handle equivalent Go constructs:
- `workflow.Context` This is a replacement for `context.Context`.
See [Tracing](/develop/go/platform/observability#tracing) for more information about context propagation.

#### Logging
### Logging

Use [`workflow.GetLogger(ctx)`](https://pkg.go.dev/go.temporal.io/sdk/workflow#GetLogger) instead of the standard
`log` package or `fmt.Println`. The SDK logger skips log messages during replay to avoid duplicates:
Expand All @@ -236,7 +236,7 @@ func MyWorkflow(ctx workflow.Context, name string) (string, error) {

For logger configuration, see [Observability: Log from a Workflow](/develop/go/platform/observability#logging).

#### Random numbers and UUIDs
### Random numbers and UUIDs

The Go SDK does not provide a seeded random source or a UUID helper. Generate these inside a
[Side Effect](/develop/go/workflows/side-effects), which records the result in the Event History and returns the
Expand All @@ -253,7 +253,7 @@ encodedID.Get(&id)
An Activity works for this too, and is the better choice when the value comes from an external system. A Side Effect is
cheaper for purely local generation.

#### Current time
### Current time

Use [`workflow.Now(ctx)`](https://pkg.go.dev/go.temporal.io/sdk/workflow#Now) instead of `time.Now()`. It returns the
time of the last Workflow Task, which is consistent across replays:
Expand All @@ -264,7 +264,7 @@ currentTime := workflow.Now(ctx)

To wait, use [`workflow.Sleep(ctx, d)`](https://pkg.go.dev/go.temporal.io/sdk/workflow#Sleep) instead of `time.Sleep`.

#### Detecting replay (advanced)
### Detecting replay (advanced)

Use [`workflow.IsReplaying(ctx)`](https://pkg.go.dev/go.temporal.io/sdk/workflow#IsReplaying) to guard code that should
only run on the first execution, such as emitting metrics or sending external notifications from an Interceptor.
Expand Down
8 changes: 4 additions & 4 deletions docs/develop/java/workflows/basics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
id: basics
title: Workflow basics - Java SDK
sidebar_label: Workflow basics
description: This section explains how to implement Workflows with the Java SDK
description: Develop a basic Workflow with the Temporal Java SDK. Define Workflow parameters, return values, and a custom Workflow Type.
toc_max_heading_level: 4
tags:
- Java SDK
- Temporal SDKs
---

## How to develop a Workflow {/* #develop-workflows */}
## Develop a basic Workflow {/* #develop-workflows */}

Workflows are the fundamental unit of a Temporal Application, and it all starts with the development of a [Workflow Definition](/workflow-definition).

Expand Down Expand Up @@ -158,7 +158,7 @@ public interface YourWorkflow {
}
```

## Define Workflow return parameters {/* #workflow-return-values */}
## Define Workflow return values {/* #workflow-return-values */}

Workflow return values must also be serializable.
Returning results, returning errors, or throwing exceptions is fairly idiomatic in each language that is supported.
Expand All @@ -174,7 +174,7 @@ Related references:
- [Data Converter](/dataconversion)
- [Java DataConverter reference](https://www.javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/common/converter/DataConverter.html)

## Customize your Workflow Type {/* #workflow-type */}
## Customize Workflow Type {/* #workflow-type */}

Workflows have a Type that is referred to as the Workflow name.

Expand Down
18 changes: 9 additions & 9 deletions docs/develop/php/workflows/basics.mdx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
id: basics
title: Workflow Basics - PHP SDK
sidebar_label: Workflow Basics
description: This section explains Workflow Basics with the PHP SDK
title: Workflow basics - PHP SDK
sidebar_label: Workflow basics
description: Develop a basic Workflow with the Temporal PHP SDK. Define Workflow parameters, return values, and a custom Workflow Type.
toc_max_heading_level: 4
tags:
- PHP SDK
- Temporal SDKs
---

## How to develop a basic Workflow {/* #develop-workflows */}
## Develop a basic Workflow {/* #develop-workflows */}

Workflows are the fundamental unit of a Temporal Application, and it all starts with the development of a [Workflow Definition](/workflow-definition).

Expand All @@ -28,7 +28,7 @@ interface FileProcessingWorkflow
}
```

### How to define Workflow parameters {/* #workflow-parameters */}
## Define Workflow parameters {/* #workflow-parameters */}

Temporal Workflows may have any number of custom parameters.
However, we strongly recommend that objects are used as parameters, so that the object's individual fields may be altered without breaking the signature of the Workflow.
Expand All @@ -50,7 +50,7 @@ interface FileProcessingWorkflow {
}
```

### How to define Workflow return parameters {/* #workflow-return-values */}
## Define Workflow return values {/* #workflow-return-values */}

Workflow return values must also be serializable.
Returning results, returning errors, or throwing exceptions is fairly idiomatic in each language that is supported.
Expand All @@ -69,7 +69,7 @@ interface FileProcessingWorkflow {
}
```

### How to customize your Workflow Type {/* #workflow-type */}
## Customize Workflow Type {/* #workflow-type */}

Workflows have a Type that are referred to as the Workflow name.

Expand All @@ -92,7 +92,7 @@ interface YourWorkflowDefinitionInterface
}
```

### Use Workflow constructors
## Use Workflow constructors

Workflow constructors are useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/handling-messages#workflow-initializers). Normally, your Workflows constructor won't have any parameters. However, if you use the `#[WorkflowInit]` attribute on your constructor, you can give it the same [Workflow parameters](/develop/php/workflows/basics#workflow-parameters) as your `#[WorkflowMethod]`.

Expand Down Expand Up @@ -127,7 +127,7 @@ class GreetingExample
}
```

### How to develop Workflow logic {/* #workflow-logic-requirements */}
## Workflow logic requirements {/* #workflow-logic-requirements */}

Workflow logic is constrained by [deterministic execution requirements](/workflow-definition#deterministic-constraints). Each Temporal SDK provides a set of APIs that can be used inside your Workflow to interact with application code outside the Workflow. used inside your Workflow to interact with external (to the Workflow) application code.

Expand Down
22 changes: 11 additions & 11 deletions docs/develop/python/workflows/basics.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
id: basics
title: Workflow Basics - Python SDK
title: Workflow basics - Python SDK
sidebar_label: Workflow basics
description: This section explains Workflow Basics with the Python SDK
description: Develop a basic Workflow with the Temporal Python SDK. Define Workflow parameters, return values, and a custom Workflow Type.
toc_max_heading_level: 4
tags:
- Python SDK
Expand Down Expand Up @@ -41,7 +41,7 @@ class YourWorkflow:
)
```

### Define Workflow parameters {/* #workflow-parameters */}
## Define Workflow parameters {/* #workflow-parameters */}

Temporal Workflows may have any number of custom parameters. However, we strongly recommend that objects are used as
parameters, so that the object's individual fields may be altered without breaking the signature of the Workflow. All
Expand All @@ -61,7 +61,7 @@ class YourParams:
name: str
```

### Define Workflow return parameters {/* #workflow-return-values */}
## Define Workflow return values {/* #workflow-return-values */}

Workflow return values must also be serializable. Returning results, returning errors, or throwing exceptions is fairly
idiomatic in each language that is supported. However, Temporal APIs that must be used to get the result of a Workflow
Expand Down Expand Up @@ -98,7 +98,7 @@ class YourWorkflow:
)
```

### Customize your Workflow Type {/* #workflow-type */}
## Customize Workflow Type {/* #workflow-type */}

Workflows have a Type that are referred to as the Workflow name.

Expand Down Expand Up @@ -126,7 +126,7 @@ class YourWorkflow:
)
```

### Use Workflow constructors
## Use Workflow constructors

Workflow constructors are useful if you have message handlers that need access to Workflow input: see [Initializing the Workflow first](/handling-messages#workflow-initializers). Normally, your Workflow `__init__` method won't have any parameters. However, if you use the `@workflow.init` decorator on your `__init__` method, you can give it the same Workflow parameters as your `@workflow.run` method.

Expand Down Expand Up @@ -155,7 +155,7 @@ class WorkflowRunSeesWorkflowInitWorkflow:
# other Workflow code
```

### Develop Workflow logic {/* #workflow-logic-requirements */}
## Workflow logic requirements {/* #workflow-logic-requirements */}

Workflow logic is constrained by [deterministic execution requirements](/workflow-definition#deterministic-constraints).
Each Temporal SDK provides a
Expand All @@ -176,7 +176,7 @@ _deterministic_.

The SDK provides replay-safe alternatives for common needs:

#### Logging
### Logging

Use [`workflow.logger`](https://python.temporal.io/temporalio.workflow.html#logger) instead of `print()` or the standard `logging` module.
The SDK logger automatically suppresses log messages during replay to avoid duplicates:
Expand All @@ -192,7 +192,7 @@ class MyWorkflow:

For logger configuration, see [Observability: Log from a Workflow](/develop/python/platform/observability#logging).

#### Random numbers and UUIDs
### Random numbers and UUIDs

Use [`workflow.random()`](https://python.temporal.io/temporalio.workflow.html#random) to get a deterministic `random.Random` instance seeded per Workflow Execution. Never use `random.random()` or other `random` module functions directly.
For UUIDs, use [`workflow.uuid4()`](https://python.temporal.io/temporalio.workflow.html#uuid4) instead of `uuid.uuid4()`:
Expand All @@ -202,15 +202,15 @@ value = workflow.random().randint(1, 100)
unique_id = workflow.uuid4()
```

#### Current time
### Current time

Use [`workflow.now()`](https://python.temporal.io/temporalio.workflow.html#now) instead of `datetime.now()` or `time.time()`. The SDK returns the time of the last Workflow Task, which is consistent across replays:

```python
current_time = workflow.now()
```

#### Detecting replay (advanced)
### Detecting replay (advanced)

Use [`workflow.unsafe.is_replaying`](https://python.temporal.io/temporalio.workflow.html#is_replaying) to guard code that should only run on the first execution, such as emitting metrics or sending external notifications from an [Interceptor](/develop/python/workers/interceptors).
:::caution
Expand Down
Loading