### Example Workflow Definition and Activity in Python Source: https://github.com/temporalio/sdk-core/blob/master/arch_docs/sdks_intro.md Defines an example activity 'say_hello' and a workflow 'ReplayExampleWorkflow' that executes the activity and a timer concurrently. This demonstrates how to schedule activities and use asynchronous operations like asyncio.gather within a Temporal workflow. ```python @activity.defn async def say_hello(name: str) -> str: return f"Hello, {name}!" @workflow.defn class ReplayExampleWorkflow: @workflow.run async def run(self, name: str) -> str: my_hello = workflow.execute_activity( say_hello, name, schedule_to_close_timeout=timedelta(seconds=5) ) timer = workflow.sleep(10) (activity_result, _) = await asyncio.gather(my_hello, timer) return activity_result ``` -------------------------------- ### Start, Signal, and Query Workflow Executions in Rust Source: https://context7.com/temporalio/sdk-core/llms.txt Demonstrates how to start a new workflow execution, send a signal to an existing workflow, and query its current status using the Temporal SDK Core client. This requires the `temporal_client` and `temporal_sdk_core_protos` crates. It takes a `RetryClient` as input and returns a `Result`. ```rust use temporal_client::{Client, RetryClient, WorkflowClientTrait}; use temporal_sdk_core_protos::temporal::api::workflowservice::v1::{ StartWorkflowExecutionRequest, SignalWorkflowExecutionRequest, QueryWorkflowRequest, TerminateWorkflowExecutionRequest, WorkflowType, TaskQueue, WorkflowQuery, }; use temporal_sdk_core_protos::temporal::api::common::v1::{Payload, Payloads, WorkflowExecution}; use std::time::Duration; async fn workflow_operations(client: RetryClient) -> Result<(), Box> { // Start workflow execution let start_request = StartWorkflowExecutionRequest { namespace: "default".to_string(), workflow_id: "payment-workflow-123".to_string(), workflow_type: Some(WorkflowType { name: "PaymentWorkflow".to_string(), }), task_queue: Some(TaskQueue { name: "payment-queue".to_string(), kind: 0, }), input: Some(Payloads { payloads: vec![Payload { metadata: [("encoding".to_string(), b"json/plain".to_vec())] .into_iter() .collect(), data: br#"{"amount": 100.50, "currency": "USD"}"#.to_vec(), }], }), workflow_execution_timeout: Some(Duration::from_secs(3600).into()), workflow_run_timeout: Some(Duration::from_secs(1800).into()), workflow_task_timeout: Some(Duration::from_secs(10).into()), identity: "payment-service".to_string(), request_id: uuid::Uuid::new_v4().to_string(), ..Default::default() }; let start_response = client.start_workflow(start_request).await?; println!("Started workflow: run_id={}", start_response.run_id); // Signal workflow let signal_request = SignalWorkflowExecutionRequest { namespace: "default".to_string(), workflow_execution: Some(WorkflowExecution { workflow_id: "payment-workflow-123".to_string(), run_id: start_response.run_id.clone(), }), signal_name: "approve_payment".to_string(), input: Some(Payloads { payloads: vec![Payload { metadata: [("encoding".to_string(), b"json/plain".to_vec())] .into_iter() .collect(), data: br#"{"approved_by": "manager@example.com"}"#.to_vec(), }], }), identity: "payment-service".to_string(), ..Default::default() }; client.signal_workflow_execution(signal_request).await?; println!("Sent signal to workflow"); // Query workflow let query_request = QueryWorkflowRequest { namespace: "default".to_string(), execution: Some(WorkflowExecution { workflow_id: "payment-workflow-123".to_string(), run_id: start_response.run_id.clone(), }), query: Some(WorkflowQuery { query_type: "getStatus".to_string(), query_args: None, }), ..Default::default() }; let query_response = client.query_workflow_execution(query_request).await?; println!("Query result: {:?}", query_response.query_result); Ok(()) } ``` -------------------------------- ### Build and Test Commands for `sdk-core` Source: https://github.com/temporalio/sdk-core/blob/master/AGENTS.md Commands for building, testing, formatting, and linting the Temporal Core SDK. These commands are enforced for pull requests to ensure code quality and functionality. Integration tests default to starting an ephemeral server. ```bash cargo build # build all crates cargo test # run unit tests cargo integ-test # integration tests (starts ephemeral server by default) cargo test --test heavy_tests # load tests -- agents do not need to run this and should not cargo fmt --all # format code cargo clippy --all -- -D warnings # lint cargo doc # generate documentation ``` -------------------------------- ### Temporal Cloud Operations API Overview Source: https://github.com/temporalio/sdk-core/blob/master/crates/common/protos/api_cloud_upstream/README.md This section provides an overview of how to use the Temporal Cloud Operations API, including setup, versioning, and connection details. ```APIDOC ## Temporal Cloud Operations API ### Description This API enables programmatic automation of Temporal Cloud operations, including user and namespace management. It is currently in Public Preview and subject to change. ### How to Use 1. **Copy Protobuf Files**: Obtain the protobuf files from the `temporal` directory. 2. **Compile with gRPC**: Use gRPC tools to generate code in your preferred programming language during your build process. 3. **Create Client Connection**: Establish a client connection using a Temporal Cloud API Key. 4. **Use Cloud Operations API Services**: Interact with the API services to manage resources. ### API Versioning Clients must include the `temporal-cloud-api-version` header in all requests. The current version is `v0.7.1`. ### URL The gRPC URL for the API is: `saas-api.tmprl.cloud:443` ### Samples Refer to the following sample repositories for usage examples: - **Go**: [cloud-samples-go](https://github.com/temporal/cloud-samples-go) - **TypeScript**: [temporal-cloud-api-client-typescript](https://github.com/steveandroulakis/temporal-cloud-api-client-typescript) - **Java**: [temporal-cloud-api-client-java](https://github.com/steveandroulakis/temporal-cloud-api-client-java) - **Kotlin**: [temporal-cloud-api-client-kotlin](https://github.com/steveandroulakis/temporal-cloud-api-client-kotlin) ``` -------------------------------- ### Define a Temporal Activity in Python Source: https://github.com/temporalio/sdk-core/blob/master/arch_docs/sdks_intro.md Defines a simple 'say_hello' activity using the Temporalio SDK. Activities can run arbitrary code, are subject to retries and timeouts, and should be idempotent. This example returns a greeting string. ```python from temporalio import activity @activity.defn async def say_hello(name: str) -> str: return f"Hello, {name}!" ``` -------------------------------- ### Python Workflow and Activity Definition Source: https://github.com/temporalio/sdk-core/blob/master/ARCHITECTURE.md Defines a simple 'SayHello' workflow that executes a 'say_hello' activity. The workflow takes a name as input and returns a greeting. The activity also takes a name and returns a formatted greeting string. This example showcases the basic structure for defining workflows and activities in Python using the Temporal SDK. ```python @workflow.defn class SayHello: @workflow.run async def run(self, name: str) -> str: return await workflow.execute_activity( say_hello, name, schedule_to_close_timeout=timedelta(seconds=5) ) @activity.defn async def say_hello(name: str) -> str: return f"Hello, {name}!" ``` -------------------------------- ### Initialize Telemetry for Debugging in Rust Tests Source: https://github.com/temporalio/sdk-core/blob/master/README.md Initializes the tracing system for debugging within Rust tests. This function should be called at the start of a test to enable global tracing output to stdout. Customization options exist for exporting tracing data to an OTel collector. ```rust crate::telemetry::telemetry_init_fallback(); ``` -------------------------------- ### Poll and Process Workflow Activations with Completions in Rust Source: https://context7.com/temporalio/sdk-core/llms.txt This Rust code snippet demonstrates how to poll for workflow activations from the Temporal worker, process the activation jobs (like starting a workflow or handling timers), and then complete the activation with generated commands. It includes error handling for polling and processing. ```rust use temporal_sdk_core::Worker; use temporal_sdk_core_protos::coresdk::workflow_activation::{ WorkflowActivation, WorkflowActivationJob, workflow_activation_job, }; use temporal_sdk_core_protos::coresdk::workflow_completion::{ WorkflowActivationCompletion, workflow_activation_completion, }; use temporal_sdk_core_protos::coresdk::workflow_commands::{ CompleteWorkflowExecution, WorkflowCommand, }; use std::collections::HashMap; use std::sync::Arc; async fn workflow_execution_loop(worker: Arc) -> Result<(), Box> { loop { // Poll for workflow activation let activation = match worker.poll_workflow_activation().await { Ok(activation) => activation, Err(PollError::ShutDown) => { println!("Worker shutting down"); break; } Err(e) => { eprintln!("Poll error: {:?}", e); continue; } }; println!("Received activation for workflow run: {}", activation.run_id); // Process activation jobs let mut commands = Vec::new(); for job in activation.jobs { match job.variant { Some(workflow_activation_job::Variant::StartWorkflow(start)) => { println!("Starting workflow: {}", start.workflow_type); // Execute workflow logic and generate commands commands.push(WorkflowCommand { variant: Some(workflow_command::Variant::CompleteWorkflowExecution( CompleteWorkflowExecution { result: Some(Payload { metadata: HashMap::new(), data: br#"{"result": "success"}"#.to_vec(), }), } )), }); } Some(workflow_activation_job::Variant::FireTimer(timer)) => { println!("Timer fired: seq={}", timer.seq); } Some(workflow_activation_job::Variant::ResolveActivity(resolution)) => { println!("Activity resolved: seq={}", resolution.seq); } _ => {} } } // Complete workflow activation let completion = WorkflowActivationCompletion { run_id: activation.run_id.clone(), status: Some(workflow_activation_completion::Status::Successful( workflow_activation_completion::Success { commands, } )), }; worker.complete_workflow_activation(completion).await?; println!("Completed activation for run: {}", activation.run_id); } Ok(()) } ``` -------------------------------- ### Execute a Temporal Workflow using Python Client Source: https://github.com/temporalio/sdk-core/blob/master/arch_docs/sdks_intro.md Demonstrates how to connect to a Temporal server and execute a workflow using the Temporalio Python client. It initiates the 'SayHello' workflow with a given name and prints the result. Requires a running Temporal server and the workflow definition. ```python from temporalio.client import Client # Import the workflow from the previous code from .workflows import SayHello async def main(): client = await Client.connect("localhost:7233") result = await client.execute_workflow( SayHello.run, "my name", id="my-workflow-id", task_queue="my-task-queue") print(f"Result: {result}") ``` -------------------------------- ### Fetch Java Testserver Protobufs using Git Read-Tree Source: https://github.com/temporalio/sdk-core/blob/master/README.md Explains how to fetch Java testserver protobufs using Git's read-tree command. This involves adding the SDK-Java repository as a remote, removing existing protos, and then pulling and committing the desired subdirectory into the Core SDK's proto directory. ```bash # add sdk-java as a remote if you have not already git remote add -f -t master --no-tags testsrv-protos git@github.com:temporalio/sdk-java.git # delete existing protos git rm -rf sdk-core-protos/protos/testsrv_upstream # pull from upstream & commit git read-tree --prefix sdk-core-protos/protos/testsrv_upstream -u testsrv-protos/master:temporal-test-server/src/main/proto git commit ``` -------------------------------- ### Configure Client Retry and Error Handling (Rust) Source: https://context7.com/temporalio/sdk-core/llms.txt Illustrates how to configure advanced retry mechanisms and handle errors for Temporal clients. This involves setting up `RetryConfig`, `ClientOptions` including proxy and keep-alive settings, and demonstrating how to interpret retryable vs. non-retryable errors. Dependencies include `temporal_client` and `temporal_sdk_core_protos`. ```rust use temporal_client::{ClientOptions, RetryClient, RetryConfig, RetryError}; use temporal_sdk_core_protos::temporal::api::workflowservice::v1::StartWorkflowExecutionRequest; use std::time::Duration; use url::Url; async fn resilient_client_operations() -> Result<(), Box> { let retry_config = RetryConfig { initial_interval: Duration::from_millis(50), randomization_factor: 0.2, multiplier: 2.0, max_interval: Duration::from_secs(30), max_elapsed_time: Some(Duration::from_secs(300)), max_retries: 5, }; let client_options = ClientOptions::builder() .target_url(Url::parse("https://temporal.example.com:7233")?) .retry_options(retry_config) .keep_alive(Some(ClientKeepAliveOptions { // Assuming ClientKeepAliveOptions is defined elsewhere interval: Duration::from_secs(30), timeout: Duration::from_secs(15), })) .http_connect_proxy(Some(HttpConnectProxyOptions { // Assuming HttpConnectProxyOptions is defined elsewhere target_addr: "proxy.example.com:8080".parse()?, })) .build(); let client = client_options.connect("production", None).await?; // Retry logic is automatic - client handles transient failures match client.start_workflow(start_request).await { // Assuming start_request is defined elsewhere Ok(response) => { println!("Workflow started: {}", response.run_id); } Err(e) if e.is_retryable() => { eprintln!("Retryable error (already retried): {:?}", e); } Err(e) => { eprintln!("Non-retryable error: {:?}", e); return Err(e.into()); } } Ok(()) } ``` -------------------------------- ### Initialize and Configure Temporal Worker in Rust Source: https://context7.com/temporalio/sdk-core/llms.txt This snippet demonstrates how to initialize and configure a worker in the Temporal SDK Core using Rust. It covers setting up the runtime with telemetry (logging and Prometheus metrics), connecting a client to the Temporal service, and defining comprehensive worker configurations including task queue, caching, timeouts, task types, versioning strategy, and resource-based tuning via a TunerBuilder. The worker is then initialized and ready to poll for tasks. ```rust use temporal_sdk_core::{init_worker, CoreRuntime, RuntimeOptions, TelemetryOptions}; use temporal_sdk_core_protos::coresdk::workflow_activation::WorkflowActivation; use temporal_sdk_core_protos::coresdk::workflow_completion::WorkflowActivationCompletion; use temporal_client::ClientOptions; use url::Url; use std::time::Duration; use std::sync::Arc; // Assuming these are defined elsewhere or need to be imported struct LoggingOptions { console: bool, forward: bool, filter: String } struct MetricsOptions { prometheus: Option, opentelemetry: Option<()> } struct PrometheusExporterOptions { bind_address: std::net::SocketAddr } struct WorkerConfig { namespace: String, task_queue: String, max_cached_workflows: u32, sticky_queue_schedule_to_start_timeout: Duration, max_heartbeat_throttle_interval: Duration, task_types: WorkerTaskTypes, versioning_strategy: WorkerVersioningStrategy, tuner: Option>, } impl WorkerConfig { fn builder() -> Self { unimplemented!() } } struct WorkerTaskTypes { enable_workflows: bool, enable_local_activities: bool, enable_remote_activities: bool, enable_nexus: bool } enum WorkerVersioningStrategy { None { build_id: String } } struct TunerBuilder { workflow_slot_supplier: FixedSizeSlotSupplier, activity_slot_supplier: FixedSizeSlotSupplier } impl TunerBuilder { fn default() -> Self { unimplemented!() } fn workflow_slot_supplier(mut self, supplier: FixedSizeSlotSupplier) -> Self { self } fn activity_slot_supplier(mut self, supplier: FixedSizeSlotSupplier) -> Self { self } fn build() -> Self { unimplemented!() } } struct FixedSizeSlotSupplier { size: u32 } impl FixedSizeSlotSupplier { fn new(size: u32) -> Self { unimplemented!() } } #[tokio::main] async fn main() -> Result<(), Box> { // Initialize runtime with telemetry let telemetry_options = TelemetryOptions::builder() .logging(Some(LoggingOptions { console: true, forward: true, filter: "info".to_string(), })) .metrics(Some(MetricsOptions { prometheus: Some(PrometheusExporterOptions { bind_address: "0.0.0.0:9090".parse()?, }), opentelemetry: None, })) .build(); let runtime_options = RuntimeOptions::builder() .telemetry_options(telemetry_options) .build()?; let runtime = CoreRuntime::new_assume_tokio(runtime_options)?; // Connect client let client_options = ClientOptions::builder() .target_url(Url::parse("http://localhost:7233")?) .client_name("my-worker") .client_version("1.0.0") .build(); let client = client_options .connect_no_namespace(runtime.telemetry().get_temporal_metric_meter()) .await?; // Configure worker with resource-based tuning let worker_config = WorkerConfig::builder() .namespace("default") .task_queue("my-task-queue") .max_cached_workflows(1000) .sticky_queue_schedule_to_start_timeout(Duration::from_secs(5)) .max_heartbeat_throttle_interval(Duration::from_secs(60)) .task_types(WorkerTaskTypes { enable_workflows: true, enable_local_activities: true, enable_remote_activities: true, enable_nexus: false, }) .versioning_strategy(WorkerVersioningStrategy::None { build_id: "v1.0.0".to_string() }) .tuner(Some(Arc::new( TunerBuilder::default() .workflow_slot_supplier(FixedSizeSlotSupplier::new(100)) .activity_slot_supplier(FixedSizeSlotSupplier::new(200)) .build() ))) .build()?; // Create worker let worker = init_worker(&runtime, worker_config, client)?; // Worker is ready to poll for tasks println!("Worker initialized on task queue: my-task-queue"); Ok(()) } ``` -------------------------------- ### Establish Temporal Client Connection with Retry and TLS in Rust Source: https://context7.com/temporalio/sdk-core/llms.txt This snippet demonstrates how to establish a connection to a Temporal server using the `temporalio-client` crate in Rust. It includes configuration for TLS with certificate/key loading and comprehensive retry options for robust connection management. The connection is made to the 'default' namespace. ```rust use temporal_client::{ClientOptions, RetryClient}; use url::Url; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), Box> { // Configure client with TLS and retry options let client_options = ClientOptions::builder() .target_url(Url::parse("https://temporal.example.com:7233")?) .client_name("my-service") .client_version("1.0.0") .identity("worker-1") .tls_options(Some(TlsOptions { server_root_ca_cert: Some(std::fs::read("ca.pem")?), client_cert: Some(std::fs::read("client-cert.pem")?), client_private_key: Some(std::fs::read("client-key.pem")?), domain: Some("temporal.example.com".to_string()), })) .retry_options(RetryOptions { initial_interval: Duration::from_millis(100), randomization_factor: 0.2, multiplier: 1.5, max_interval: Duration::from_secs(10), max_elapsed_time: Some(Duration::from_secs(60)), max_retries: 10, }) .keep_alive(Some(ClientKeepAliveOptions { interval: Duration::from_secs(30), timeout: Duration::from_secs(15), })) .build(); // Connect to namespace with metrics let client = client_options .connect("default", None) .await?; println!("Connected to Temporal server"); Ok(()) } ``` -------------------------------- ### Fetch Replay Histories using Cargo Bin Source: https://github.com/temporalio/sdk-core/blob/master/README.md Provides a command to fetch replay histories in binary format from a local Temporal Docker server. This utility is used by tests that need to replay stored histories. The Temporal service address can be configured via the `TEMPORAL_SERVICE_ADDRESS` environment variable. ```bash cargo run --bin histfetch {workflow_id} [{run_id}] ``` -------------------------------- ### Define a Temporal Workflow in Python Source: https://github.com/temporalio/sdk-core/blob/master/arch_docs/sdks_intro.md Defines a simple 'SayHello' workflow using the Temporalio SDK. It executes a single activity and returns its result. The workflow code must be deterministic and use SDK-specific APIs. ```python from datetime import timedelta from temporalio import workflow @workflow.defn class SayHello: @workflow.run async def run(self, name: str) -> str: return await workflow.execute_activity( say_hello, name, schedule_to_close_timeout=timedelta(seconds=5) ) ``` -------------------------------- ### Run a Temporal Worker in Python Source: https://github.com/temporalio/sdk-core/blob/master/arch_docs/sdks_intro.md Sets up and runs a Temporal worker using the Temporalio Python SDK. The worker polls for tasks on a specified 'task_queue' and executes the provided workflows and activities. It requires a connected client and definitions for workflows and activities. ```python from temporalio.client import Client from temporalio.worker import Worker from .activities import say_hello from .workflows import SayHello async def main(): client = await Client.connect("localhost:7233") worker = Worker( client, task_queue="my-task-queue", workflows=[SayHello], activities=[say_hello]) await worker.run() ``` -------------------------------- ### Fetch Workflow History Utility Source: https://github.com/temporalio/sdk-core/blob/master/AGENTS.md A command-line utility to fetch workflow histories. This binary is located within the `crates/core/src/histfetch.rs` file. ```bash cargo run --bin histfetch [run_id] ``` -------------------------------- ### Configure Resource-Based Worker Slot Tuning (Rust) Source: https://context7.com/temporalio/sdk-core/llms.txt Demonstrates how to configure dynamic resource-based slot management for Temporal workers using `TunerBuilder`. It covers fixed-size, resource-based, and hybrid approaches for workflow, activity, and local activity slot suppliers. Dependencies include `temporal_sdk_core`. ```rust use temporal_sdk_core::{ TunerBuilder, ResourceBasedTuner, ResourceBasedSlotsOptions, FixedSizeSlotSupplier, SlotSupplierOptions, }; use std::sync::Arc; use std::time::Duration; fn configure_worker_tuning() -> Arc { // Option 1: Fixed size slots let fixed_tuner = TunerBuilder::default() .workflow_slot_supplier(FixedSizeSlotSupplier::new(100)) .activity_slot_supplier(FixedSizeSlotSupplier::new(200)) .local_activity_slot_supplier(FixedSizeSlotSupplier::new(100)) .build(); // Option 2: Resource-based tuning let resource_opts = ResourceBasedSlotsOptions::builder() .target_memory_usage(0.8) // 80% memory target .target_cpu_usage(0.8) // 80% CPU target .minimum_slots(10) .maximum_slots(500) .ramp_throttle(Duration::from_millis(50)) .build(); let resource_tuner = ResourceBasedTuner::new(resource_opts); // Option 3: Hybrid approach let hybrid_tuner = TunerBuilder::default() .workflow_slot_supplier(ResourceBasedSlotSupplier::new( ResourceBasedSlotsOptions::builder() .target_memory_usage(0.7) .target_cpu_usage(0.7) .minimum_slots(20) .maximum_slots(200) .build() )) .activity_slot_supplier(FixedSizeSlotSupplier::new(300)) .build(); Arc::new(hybrid_tuner) } ``` -------------------------------- ### Register Activities and Workflow in Rust SDK Source: https://context7.com/temporalio/sdk-core/llms.txt This Rust code snippet initializes a Temporal worker, registers several activities with type-safe inputs and outputs, and defines a workflow that calls these activities. It requires the `temporal-sdk` and `serde` crates. The workflow logic handles activity execution and determines the final workflow outcome. ```rust use temporal_sdk::{ Worker, ActContext, WfContext, WfExitValue, sdk_client_options, CoreRuntime, RuntimeOptions, TelemetryOptions, }; use serde::{Deserialize, Serialize}; use url::Url; use std::time::Duration; use std::sync::Arc; #[derive(Deserialize, Serialize)] struct OrderInput { order_id: String, items: Vec, total: f64, } #[derive(Deserialize, Serialize)] struct OrderResult { order_id: String, status: String, confirmation_number: String, } #[tokio::main] async fn main() -> Result<(), Box> { // Initialize runtime let telemetry_options = TelemetryOptions::builder().build(); let runtime_options = RuntimeOptions::builder() .telemetry_options(telemetry_options) .build()?; let runtime = CoreRuntime::new_assume_tokio(runtime_options)?; // Connect client let client_options = sdk_client_options(Url::parse("http://localhost:7233")?) .build(); let client = client_options.connect("default", None).await?; // Create worker config let worker_config = WorkerConfig::builder() .namespace("default") .task_queue("order-processing") .task_types(WorkerTaskTypes::all()) .versioning_strategy(WorkerVersioningStrategy::None { build_id: "order-service-1.0".to_string(), }) .build()?; let core_worker = init_worker(&runtime, worker_config, client)?; let mut worker = Worker::new_from_core(Arc::new(core_worker), "order-processing"); // Register activities worker.register_activity( "validate_inventory", |_ctx: ActContext, input: OrderInput| async move { println!("Validating inventory for order: {}", input.order_id); tokio::time::sleep(Duration::from_secs(1)).await; Ok(true) }, ); worker.register_activity( "process_payment", |_ctx: ActContext, input: OrderInput| async move { println!("Processing payment: ${}", input.total); tokio::time::sleep(Duration::from_secs(2)).await; Ok(format!("TXN_{}", uuid::Uuid::new_v4())) }, ); worker.register_activity( "ship_order", |_ctx: ActContext, input: OrderInput| async move { println!("Shipping order: {}", input.order_id); tokio::time::sleep(Duration::from_secs(1)).await; Ok(OrderResult { order_id: input.order_id, status: "shipped".to_string(), confirmation_number: format!("SHIP_{}", uuid::Uuid::new_v4()), }) }, ); // Register workflow worker.register_wf("OrderWorkflow", |ctx: WfContext| async move { let input: OrderInput = ctx.get_args()?; // Validate inventory let valid: bool = ctx.activity("validate_inventory") .start_with_args(&input) .await?; if !valid { return Ok(WfExitValue::Normal( serde_json::to_string(&"Insufficient inventory")? )); } // Process payment let _txn_id: String = ctx.activity("process_payment") .start_with_args(&input) .await?; // Ship order let result: OrderResult = ctx.activity("ship_order") .start_with_args(&input) .await?; Ok(WfExitValue::Normal(serde_json::to_string(&result)?)) }); // Run worker println!("Worker running on task queue: order-processing"); worker.run().await?; Ok(()) } ``` -------------------------------- ### Update Upstream Protobuf Files using Git Subtree Source: https://github.com/temporalio/sdk-core/blob/master/README.md Demonstrates how to update upstream protobuf files within the Core SDK repository using Git's subtree functionality. This process is used for API upstream and cloud upstream protos, requiring specific Git commands to pull changes from remote repositories. ```bash git pull --squash --rebase=false -s subtree ssh://git@github.com/temporalio/api.git master --allow-unrelated-histories ``` -------------------------------- ### Implement Worker Graceful Shutdown (Rust) Source: https://context7.com/temporalio/sdk-core/llms.txt Provides a method for gracefully shutting down a Temporal worker. It involves spawning the worker in a separate task, listening for shutdown signals (like Ctrl+C), initiating the shutdown process, waiting for in-flight tasks to complete, and finalizing the shutdown. Dependencies include `temporal_sdk_core` and `tokio::signal`. ```rust use temporal_sdk_core::Worker; use tokio::signal; use std::sync::Arc; async fn run_worker_with_graceful_shutdown( worker: Arc ) -> Result<(), Box> { // Spawn worker task let worker_clone = worker.clone(); let worker_handle = tokio::spawn(async move { loop { match worker_clone.poll_workflow_activation().await { Ok(activation) => { // Process activation... let completion = process_activation(activation).await; // Assuming process_activation is defined elsewhere worker_clone.complete_workflow_activation(completion).await.ok(); } Err(PollError::ShutDown) => break, // Assuming PollError is defined elsewhere Err(e) => eprintln!("Poll error: {:?}", e), } } }); // Wait for shutdown signal signal::ctrl_c().await?; println!("Shutdown signal received, gracefully stopping worker..."); // Initiate shutdown worker.initiate_shutdown(); // Wait for in-flight tasks to complete worker.shutdown().await; // Wait for worker task to complete worker_handle.await?; // Finalize shutdown worker.finalize_shutdown().await; println!("Worker shutdown complete"); Ok(()) } ``` -------------------------------- ### Poll and Process Activity Tasks with Heartbeats in Rust Source: https://context7.com/temporalio/sdk-core/llms.txt This Rust function polls for activity tasks from the Temporal service. Upon receiving a task, it simulates activity execution by sending periodic heartbeats and then completes the task with either a success or failure result. It handles shutdown signals and other polling errors. ```rust use temporal_sdk_core::Worker; use temporal_sdk_core_protos::coresdk::activity_task::{ActivityTask, activity_task}; use temporal_sdk_core_protos::coresdk::activity_result::{ ActivityTaskCompletion, activity_execution_result, ActivityExecutionResult, }; use temporal_sdk_core_protos::coresdk::common::Payload; use std::collections::HashMap; use std::error::Error; use std::sync::Arc; use std::time::Duration; async fn activity_execution_loop(worker: Arc) -> Result<(), Box> { loop { // Poll for activity task let task = match worker.poll_activity_task().await { Ok(task) => task, Err(PollError::ShutDown) => { println!("Worker shutting down"); break; } Err(e) => { eprintln!("Activity poll error: {:?}", e); continue; } }; let task_token = task.task_token.clone(); // Process activity task if let Some(activity_task::Variant::Start(start)) = task.variant { println!("Executing activity: {} (seq={})", start.activity_type, start.activity_id); // Simulate activity execution with heartbeats let worker_clone = worker.clone(); let task_token_clone = task_token.clone(); tokio::spawn(async move { for i in 1..=5 { // Send heartbeat worker_clone.record_activity_heartbeat(ActivityHeartbeat { task_token: task_token_clone.clone(), details: vec![Payload { metadata: HashMap::new(), data: format!(r#"{{\"progress\": {}}}"#, i * 20).into_bytes(), }], }); tokio::time::sleep(Duration::from_secs(1)).await; } }); // Execute activity logic let result = execute_activity(&start.activity_type, &start.input).await; // Complete activity task let completion = ActivityTaskCompletion { task_token, result: Some(ActivityExecutionResult { status: Some(match result { Ok(output) => activity_execution_result::Status::Completed( activity_execution_result::Success { result: Some(Payload { metadata: HashMap::new(), data: output, }), } ), Err(e) => activity_execution_result::Status::Failed( activity_execution_result::Failure { failure: Some(Failure { message: e.to_string(), ..Default::default() }), } ), }), }), }; worker.complete_activity_task(completion).await?; } } Ok(()) } async fn execute_activity(activity_type: &str, input: &[Payload]) -> Result, anyhow::Error> { match activity_type { "process_payment" => Ok(br#"{{\"payment_id\": \"txn_12345\", \"status\": \"completed\"}}"#.to_vec()), "send_email" => Ok(br#"{{\"email_sent\": true, \"message_id\": \"msg_67890\"}}"#.to_vec()), _ => Err(anyhow::anyhow!("Unknown activity type: {}", activity_type)), } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.