Skip to content

Commit 51d27ac

Browse files
authored
Merge branch 'main' into tags-column-ai-integrations
2 parents fc161c6 + 26e515f commit 51d27ac

42 files changed

Lines changed: 3141 additions & 27 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/develop/go/activities/standalone-activities.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ the failure is returned as an error.
347347
Or use the Temporal CLI to wait for a result by Activity ID:
348348

349349
```bash
350-
./temporal activity result --activity-id my-standalone-activity-id
350+
./temporal activity result --activity-id standalone_activity_helloworld_ActivityID
351351
```
352352

353353
## Get a handle to an existing Standalone Activity {#get-activity-handle}
@@ -359,7 +359,7 @@ Both `ActivityID` and `RunID` are required.
359359

360360
```go
361361
handle := c.GetActivityHandle(client.GetActivityHandleOptions{
362-
ActivityID: "my-standalone-activity-id",
362+
ActivityID: "standalone_activity_helloworld_ActivityID",
363363
RunID: "the-run-id",
364364
})
365365

docs/develop/python/workers/basics.mdx

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
id: basics
3+
title: Activity basics - Rust SDK
4+
sidebar_label: Activity basics
5+
description: This section explains how to implement Activities with the Rust SDK
6+
toc_max_heading_level: 4
7+
keywords:
8+
- Rust SDK
9+
tags:
10+
- Rust SDK
11+
- Temporal SDKs
12+
---
13+
14+
## Develop a basic Activity {#develop-activities}
15+
16+
One of the primary things that Workflows do is orchestrate the execution of Activities. An Activity is a normal function or method execution that's intended to execute a single, well-defined action (either short or long-running), such as querying a database, calling a third-party API, or transcoding a media file.
17+
18+
An Activity can interact with the world outside the Temporal Platform or use a Temporal Client to interact with a Temporal Service. For the Workflow to be able to execute the Activity, you need to define the [Activity Definition](/activity-definition).
19+
20+
The `#[activities]` macro marks an `impl` block as containing Activity definitions. Each method decorated with `#[activity]` becomes an Activity that can be invoked from a Workflow.
21+
22+
Here's an example of an Activity:
23+
24+
```rust
25+
use temporalio_sdk::activities::{ActivityContext, ActivityError};
26+
use temporalio_macros::activities;
27+
28+
pub struct GreetingActivities;
29+
30+
#[activities]
31+
impl GreetingActivities {
32+
#[activity]
33+
pub async fn greet(_ctx: ActivityContext, name: String) -> Result<String, ActivityError> {
34+
Ok(format!("Hello, {}!", name))
35+
}
36+
37+
#[activity]
38+
pub async fn send_notification(_ctx: ActivityContext, message: String) -> Result<(), ActivityError> {
39+
println!("Sending notification: {}", message);
40+
Ok(())
41+
}
42+
}
43+
```
44+
45+
### Define Activity parameters {#activity-parameters}
46+
47+
There is a limit of 6 parameters that an [Activity Definition](/activity-definition) may support. There is also a limit to the total size of the data that ends up encoded into a gRPC message Payload.
48+
49+
A single argument is limited to a maximum size of 2 MB. And the total size of a gRPC message, which includes all the arguments, is limited to a maximum of 4 MB.
50+
51+
Also, keep in mind that all Payload data is recorded in the [Workflow Execution Event History](/workflow-execution/event#event-history) and large Event Histories can affect Worker performance.
52+
53+
We recommend that you use a single struct as an argument that wraps all the application data passed to Activities. This way you can change what data is passed to the Activity without breaking the function signature.
54+
55+
Each Activity method must:
56+
57+
- Be `async` (return a future)
58+
- Take `ActivityContext` as the first parameter
59+
- Return `Result<T, ActivityError>` where `T` is the return type
60+
- Be `pub` (public)
61+
62+
The `ActivityContext` parameter provides access to Activity execution information and capabilities like heartbeating. If you don't need it, you can use `_ctx` as a parameter name.
63+
64+
Activities can also take `Arc<Self>` and be registered using an instance. Here's an example using `Arc`:
65+
66+
```rust
67+
struct SleeperActivities {
68+
acts_started: Arc<Semaphore>,
69+
acts_done: Arc<Semaphore>,
70+
}
71+
72+
#[activities]
73+
impl SleeperActivities {
74+
#[activity]
75+
async fn sleeper(
76+
self: Arc<Self>,
77+
ctx: ActivityContext,
78+
_: String,
79+
) -> Result<(), ActivityError> {
80+
self.acts_started.add_permits(1);
81+
// just wait to be cancelled
82+
ctx.cancelled().await;
83+
self.acts_done.add_permits(1);
84+
Err(ActivityError::cancelled())
85+
}
86+
}
87+
```
88+
89+
Activity parameters should be serializable and deserializable using serde. Use `#[derive(Serialize, Deserialize)]` on your data types:
90+
91+
```rust
92+
use serde::{Serialize, Deserialize};
93+
use temporalio_macros::activities;
94+
use temporalio_sdk::activities::{ActivityContext, ActivityError};
95+
96+
#[derive(Serialize, Deserialize)]
97+
pub struct GreetingInput {
98+
pub greeting: String,
99+
pub name: String,
100+
}
101+
102+
pub struct GreetingActivities;
103+
104+
#[activities]
105+
impl GreetingActivities {
106+
#[activity]
107+
pub async fn compose_greeting(
108+
_ctx: ActivityContext,
109+
input: GreetingInput,
110+
) -> Result<String, ActivityError> {
111+
Ok(format!("{} {}!", input.greeting, input.name))
112+
}
113+
}
114+
```
115+
116+
### Define Activity return values {#activity-return-values}
117+
118+
All data returned from an Activity must be serializable.
119+
120+
Activity return values are subject to payload size limits in Temporal. The default payload size limit is 2MB, and there is a hard limit of 4MB for any gRPC message size in the Event History transaction. Keep in mind that all return values are recorded in a [Workflow Execution Event History](/workflow-execution/event#event-history).
121+
122+
The return type of an Activity is `Result<T, ActivityError>`. The `T` type must implement `Serialize`. Use `ApplicationFailure::new` for errors that should be retried, and `ApplicationFailure::non_retryable` for permanent failures:
123+
124+
```rust
125+
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
126+
pub struct ProcessedData {
127+
pub processed: String,
128+
}
129+
130+
#[activities]
131+
impl MyActivities {
132+
#[activity]
133+
pub async fn process_data(
134+
_ctx: ActivityContext,
135+
input: String,
136+
) -> Result<ProcessedData, ActivityError> {
137+
// If an error should be retried
138+
if !validate_input(&input) {
139+
return Err(ApplicationFailure::builder(anyhow::anyhow!("Invalid input format"))
140+
.next_retry_delay(Duration::from_secs(5))
141+
.build()
142+
.into());
143+
}
144+
145+
// If an error should not be retried
146+
if input.len() > 1000000 {
147+
return Err(ApplicationFailure::non_retryable(
148+
anyhow::anyhow!("Input too large")
149+
).into());
150+
}
151+
152+
let result = ProcessedData {
153+
processed: input.to_uppercase(),
154+
};
155+
156+
Ok(result)
157+
}
158+
}
159+
```
160+
161+
### Customize your Activity Type {#activity-type}
162+
163+
Activities have a Type that refers to the Activity name. The Activity name is used to identify Activity Types in the Workflow Execution Event History, Visibility Queries, and Metrics.
164+
165+
By default, the Activity name is the method name. You can customize it by providing a `name` parameter to the `#[activity]` macro:
166+
167+
```rust
168+
#[activities]
169+
impl GreetingActivities {
170+
#[activity(name = "compose_greeting")]
171+
pub async fn greet(_ctx: ActivityContext, name: String) -> Result<String, ActivityError> {
172+
Ok(format!("Hello, {}!", name))
173+
}
174+
175+
#[activity(name = "send_email")]
176+
pub async fn send_notification(_ctx: ActivityContext, message: String) -> Result<(), ActivityError> {
177+
println!("Sending notification: {}", message);
178+
Ok(())
179+
}
180+
}
181+
```
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
---
2+
id: execution
3+
title: Activity execution - Rust SDK
4+
description: Shows how to perform Activity execution with the Rust SDK
5+
sidebar_label: Activity execution
6+
slug: /develop/rust/activities/execution
7+
toc_max_heading_level: 3
8+
tags:
9+
- Rust SDK
10+
- Temporal SDKs
11+
- Activity
12+
---
13+
14+
## Start an Activity Execution {#activity-execution}
15+
16+
Calls to spawn [Activity Executions](/activity-execution) are written within a
17+
[Workflow Definition](/workflow-definition). The call to spawn an Activity Execution generates the
18+
[ScheduleActivityTask](/references/commands#scheduleactivitytask) Command. This results in a set of three [Activity Task](/tasks#activity-task) related Events in your Workflow Execution Event History:
19+
[ActivityTaskScheduled](/references/events#activitytaskscheduled), [ActivityTaskStarted](/references/events#activitytaskstarted), and ActivityTaskClosed.
20+
21+
A single instance of the Activity implementation may be used across multiple concurrent Activity invocations. Activity implementation code should be *idempotent*.
22+
23+
Values passed to Activities as input parameters or returned as results are recorded in the Workflow Execution history. This history is replayed to Workflow Workers during recovery. Large payloads can negatively impact Workflow performance.
24+
25+
Be mindful of the size of data passed to and from Activities. Otherwise, there are no strict limitations on Activity implementations.
26+
27+
To spawn an Activity Execution, use the Workflow context’s Activity execution APIs within your Workflow code.
28+
29+
In Rust, Activities are typically executed using `ctx.start_activity(...)`, which returns a `Future` that can be awaited.
30+
31+
```rust
32+
#[workflow_methods]
33+
impl GreetingWorkflow {
34+
#[run]
35+
pub async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<String> {
36+
let name = ctx.state(|s| s.name.clone());
37+
// Execute an activity
38+
let greeting = ctx.start_activity(
39+
MyActivities::greet,
40+
name,
41+
ActivityOptions::start_to_close_timeout(Duration::from_secs(30)),
42+
).await?;
43+
44+
println!("{}", greeting);
45+
46+
Ok(greeting)
47+
}
48+
}
49+
```
50+
51+
### Set the required Activity Timeouts {#required-timeout}
52+
53+
Activity Execution semantics rely on several timeout parameters. You need to set at least one of these:
54+
55+
* [Schedule-To-Close Timeout](/encyclopedia/detecting-activity-failures#schedule-to-close-timeout)
56+
* [Start-To-Close Timeout](/encyclopedia/detecting-activity-failures#start-to-close-timeout)
57+
58+
These are configured as part of the Activity options when scheduling the Activity. Available timeouts include:
59+
60+
- `start_to_close_timeout`
61+
- `schedule_to_close_timeout`
62+
- `with_start_to_close_timeout`
63+
- `with_schedule_to_close_timeout`
64+
65+
```rust
66+
#[workflow_methods]
67+
impl GreetingWorkflow {
68+
#[init]
69+
fn new(_ctx: &WorkflowContextView, name: String) -> Self {
70+
Self { name }
71+
}
72+
73+
#[run]
74+
pub async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<String> {
75+
let name = ctx.state(|s| s.name.clone());
76+
// Execute an activity
77+
let greeting = ctx.start_activity(
78+
MyActivities::greet,
79+
name,
80+
ActivityOptions::schedule_to_close_timeout(Duration::from_secs(30))
81+
).await?;
82+
83+
println!("{}", greeting);
84+
Ok(greeting)
85+
}
86+
}
87+
```
88+
89+
### Get the results of an Activity Execution {#get-activity-results}
90+
91+
Spawning an [Activity Execution](/activity-execution) generates a [ScheduleActivityTask](/references/commands#scheduleactivitytask) Command and returns a `Future` to the Workflow.
92+
93+
Workflows can either:
94+
95+
* `await` the result immediately (blocking progress), or
96+
* store the `Future` and await it later to allow concurrent execution.
97+
98+
In Rust, calling `.await` on the Activity invocation returns the result. If you need more control (e.g., parallel execution), you can create multiple Activity futures and await them selectively.
99+
100+
You must provide either `schedule_to_close_timeout` or `start_to_close_timeout`.
101+
102+
```rust
103+
#[workflow_methods]
104+
impl GreetingWorkflow {
105+
#[run]
106+
pub async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<String> {
107+
let name = ctx.state(|s| s.name.clone());
108+
// Execute an activity
109+
let greeting = ctx.start_activity(
110+
MyActivities::greet,
111+
name,
112+
ActivityOptions::start_to_close_timeout(Duration::from_secs(30))
113+
).await?;
114+
115+
println!("{}", greeting);
116+
Ok(greeting)
117+
}
118+
}
119+
```
120+
121+
For concurrent execution:
122+
123+
```rust
124+
use temporalio_sdk::workflows::join;
125+
126+
#[run]
127+
pub async fn run(ctx: &mut WorkflowContext<Self>) -> WorkflowResult<String> {
128+
let name = ctx.state(|s| s.name.clone());
129+
// Execute an activity
130+
let greeting = ctx.start_activity(
131+
MyActivities::greet,
132+
name,
133+
ActivityOptions::start_to_close_timeout(Duration::from_secs(30))
134+
);
135+
136+
let language = ctx.start_activity(
137+
MyActivities::call_greeting_service,
138+
ActivityLanguages::English,
139+
ActivityOptions::start_to_close_timeout(Duration::from_secs(30))
140+
);
141+
142+
// Run in parallel
143+
let (greeting_res, language_res) = join!(greeting, language);
144+
}
145+
```
146+
147+
Use direct `.await` in most cases. More advanced patterns, like parallel execution or cancellation, can be built using Rust’s async primitives.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
id: index
3+
title: Activities - TypeScript SDK
4+
sidebar_label: Activities
5+
description:
6+
This section explains how to implement Activities with the Rust SDK
7+
toc_max_heading_level: 4
8+
keywords:
9+
- Rust
10+
tags:
11+
- Rust SDK
12+
- Temporal SDKs
13+
---
14+
15+
import * as Components from '@site/src/components';
16+
17+
![Rust SDK Banner](/img/assets/banner-rust-temporal.png)
18+
19+
## Activities
20+
21+
- [Activity basics](/develop/rust/activities/basics)
22+
- [Activity execution](/develop/rust/activities/execution)
23+
- [Timeouts](/develop/rust/activities/timeouts)

0 commit comments

Comments
 (0)