@temporalio/core-bridge 1.15.0 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +172 -70
- package/lib/native.d.ts +1 -1
- package/package.json +2 -2
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.github/workflows/per-pr.yml +6 -6
- package/sdk-core/AGENTS.md +41 -30
- package/sdk-core/Cargo.toml +3 -0
- package/sdk-core/README.md +15 -9
- package/sdk-core/crates/client/Cargo.toml +4 -0
- package/sdk-core/crates/client/README.md +139 -0
- package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
- package/sdk-core/crates/client/src/callback_based.rs +7 -0
- package/sdk-core/crates/client/src/errors.rs +294 -0
- package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
- package/sdk-core/crates/client/src/lib.rs +920 -1326
- package/sdk-core/crates/client/src/metrics.rs +24 -33
- package/sdk-core/crates/client/src/options_structs.rs +457 -0
- package/sdk-core/crates/client/src/replaceable.rs +5 -4
- package/sdk-core/crates/client/src/request_extensions.rs +8 -9
- package/sdk-core/crates/client/src/retry.rs +99 -54
- package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +61 -2
- package/sdk-core/crates/common/build.rs +742 -12
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
- package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
- package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -5
- package/sdk-core/crates/common/src/activity_definition.rs +20 -0
- package/sdk-core/crates/common/src/data_converters.rs +770 -0
- package/sdk-core/crates/common/src/envconfig.rs +5 -0
- package/sdk-core/crates/common/src/lib.rs +15 -211
- package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
- package/sdk-core/crates/common/src/priority.rs +110 -0
- package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
- package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
- package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
- package/sdk-core/crates/common/src/protos/mod.rs +122 -27
- package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
- package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
- package/sdk-core/crates/common/src/telemetry.rs +264 -4
- package/sdk-core/crates/common/src/worker.rs +68 -603
- package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
- package/sdk-core/crates/macros/Cargo.toml +5 -1
- package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
- package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
- package/sdk-core/crates/macros/src/lib.rs +138 -512
- package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
- package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
- package/sdk-core/crates/sdk/Cargo.toml +19 -6
- package/sdk-core/crates/sdk/README.md +415 -0
- package/sdk-core/crates/sdk/src/activities.rs +417 -0
- package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
- package/sdk-core/crates/sdk/src/lib.rs +757 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
- package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
- package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
- package/sdk-core/crates/sdk/src/workflows.rs +711 -0
- package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
- package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
- package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
- package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
- package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
- package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
- package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
- package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
- package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
- package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
- package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
- package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
- package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
- package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
- package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
- package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
- package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
- package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
- package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
- package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
- package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
- package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
- package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
- package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
- package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
- package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
- package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
- package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
- package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +205 -318
- package/src/metrics.rs +22 -30
- package/src/runtime.rs +4 -5
- package/src/worker.rs +16 -19
- package/ts/native.ts +1 -1
- package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
- package/sdk-core/crates/common/src/errors.rs +0 -85
- package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
- package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
- package/sdk-core/crates/sdk/src/app_data.rs +0 -37
- package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
use crate::data_converters::{TemporalDeserializable, TemporalSerializable};
|
|
2
|
+
|
|
3
|
+
/// Implement on a marker struct to define a workflow.
|
|
4
|
+
///
|
|
5
|
+
/// Typically, you will want to use the `#[workflow]` and `#[workflow_methods]` macros to define
|
|
6
|
+
/// workflows. However, this trait may be implemented manually if desired.
|
|
7
|
+
pub trait WorkflowDefinition {
|
|
8
|
+
/// Type of the input argument to the workflow
|
|
9
|
+
type Input: TemporalDeserializable + TemporalSerializable + 'static;
|
|
10
|
+
/// Type of the output of the workflow
|
|
11
|
+
type Output: TemporalDeserializable + TemporalSerializable + 'static;
|
|
12
|
+
/// The workflow type name
|
|
13
|
+
fn name(&self) -> &str;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/// Implement on a marker struct to define a query.
|
|
17
|
+
///
|
|
18
|
+
/// Typically, you will want to use the `#[query]` attribute inside a `#[workflow_methods]` macro
|
|
19
|
+
/// to define updates. However, this trait may be implemented manually if desired.
|
|
20
|
+
pub trait QueryDefinition {
|
|
21
|
+
/// The workflow type this query belongs to
|
|
22
|
+
type Workflow: WorkflowDefinition;
|
|
23
|
+
/// Type of the input argument to the query.
|
|
24
|
+
type Input: TemporalDeserializable + TemporalSerializable + 'static;
|
|
25
|
+
/// Type of the output of the query.
|
|
26
|
+
type Output: TemporalDeserializable + TemporalSerializable + 'static;
|
|
27
|
+
|
|
28
|
+
/// The workflow type name.
|
|
29
|
+
fn name(&self) -> &str;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Implement on a marker struct to define a signal.
|
|
33
|
+
///
|
|
34
|
+
/// Typically, you will want to use the `#[signal]` attribute inside a `#[workflow_methods]` macro
|
|
35
|
+
/// to define signals. However, this trait may be implemented manually if desired.
|
|
36
|
+
pub trait SignalDefinition {
|
|
37
|
+
/// The workflow type this signal belongs to
|
|
38
|
+
type Workflow: WorkflowDefinition;
|
|
39
|
+
/// Type of the input argument to the signal.
|
|
40
|
+
type Input: TemporalDeserializable + TemporalSerializable + 'static;
|
|
41
|
+
|
|
42
|
+
/// The workflow type name.
|
|
43
|
+
fn name(&self) -> &str;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// Implement on a marker struct to define an update.
|
|
47
|
+
///
|
|
48
|
+
/// Typically, you will want to use the `#[update]` attribute inside a `#[workflow_methods]` macro
|
|
49
|
+
/// to define updates. However, this trait may be implemented manually if desired.
|
|
50
|
+
pub trait UpdateDefinition {
|
|
51
|
+
/// The workflow type this update belongs to
|
|
52
|
+
type Workflow: WorkflowDefinition;
|
|
53
|
+
/// Type of the input argument to the update.
|
|
54
|
+
type Input: TemporalDeserializable + TemporalSerializable + 'static;
|
|
55
|
+
/// Type of the output of the update.
|
|
56
|
+
type Output: TemporalDeserializable + TemporalSerializable + 'static;
|
|
57
|
+
|
|
58
|
+
/// The workflow type name.
|
|
59
|
+
fn name(&self) -> &str;
|
|
60
|
+
}
|
|
@@ -5,6 +5,10 @@ edition = "2024"
|
|
|
5
5
|
authors = ["Temporal Technologies Inc. <sdk@temporal.io>"]
|
|
6
6
|
license-file = { workspace = true }
|
|
7
7
|
description = "Procmacros used in Temporal Core & Rust SDKs"
|
|
8
|
+
homepage = "https://temporal.io/"
|
|
9
|
+
repository = "https://github.com/temporalio/sdk-core"
|
|
10
|
+
keywords = ["temporal", "workflow", "macros"]
|
|
11
|
+
categories = ["development-tools"]
|
|
8
12
|
|
|
9
13
|
[lib]
|
|
10
14
|
proc-macro = true
|
|
@@ -12,7 +16,7 @@ proc-macro = true
|
|
|
12
16
|
[dependencies]
|
|
13
17
|
derive_more = { workspace = true }
|
|
14
18
|
proc-macro2 = "1.0"
|
|
15
|
-
syn = { version = "2.0", features = ["default", "extra-traits"] }
|
|
19
|
+
syn = { version = "2.0", features = ["default", "extra-traits", "full"] }
|
|
16
20
|
quote = "1.0"
|
|
17
21
|
|
|
18
22
|
[dev-dependencies]
|
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
use crate::macro_utils::{
|
|
2
|
+
extract_allow_attrs, generate_marker_struct, method_name_to_pascal_case, type_name_string,
|
|
3
|
+
type_to_snake_case,
|
|
4
|
+
};
|
|
5
|
+
use proc_macro::TokenStream;
|
|
6
|
+
use proc_macro2::TokenStream as TokenStream2;
|
|
7
|
+
use quote::{format_ident, quote, quote_spanned};
|
|
8
|
+
use syn::{
|
|
9
|
+
Attribute, FnArg, ImplItem, ItemImpl, ReturnType, Type, TypePath,
|
|
10
|
+
parse::{Parse, ParseStream},
|
|
11
|
+
spanned::Spanned,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
pub(crate) struct ActivitiesDefinition {
|
|
15
|
+
impl_block: ItemImpl,
|
|
16
|
+
activities: Vec<ActivityMethod>,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#[derive(Default)]
|
|
20
|
+
struct ActivityAttributes {
|
|
21
|
+
name_override: Option<syn::Expr>,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
struct ActivityMethod {
|
|
25
|
+
method: syn::ImplItemFn,
|
|
26
|
+
attributes: ActivityAttributes,
|
|
27
|
+
is_async: bool,
|
|
28
|
+
is_static: bool,
|
|
29
|
+
input_types: Vec<Type>,
|
|
30
|
+
output_type: Option<Type>,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
impl Parse for ActivitiesDefinition {
|
|
34
|
+
fn parse(input: ParseStream) -> syn::Result<Self> {
|
|
35
|
+
let impl_block: ItemImpl = input.parse()?;
|
|
36
|
+
let mut activities = Vec::new();
|
|
37
|
+
|
|
38
|
+
// Extract methods marked with #[activity]
|
|
39
|
+
for item in &impl_block.items {
|
|
40
|
+
if let ImplItem::Fn(method) = item {
|
|
41
|
+
let has_activity_attr = method
|
|
42
|
+
.attrs
|
|
43
|
+
.iter()
|
|
44
|
+
.any(|attr| attr.path().is_ident("activity"));
|
|
45
|
+
|
|
46
|
+
if has_activity_attr {
|
|
47
|
+
let activity = parse_activity_method(method)?;
|
|
48
|
+
activities.push(activity);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
Ok(ActivitiesDefinition {
|
|
54
|
+
impl_block,
|
|
55
|
+
activities,
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fn parse_activity_method(method: &syn::ImplItemFn) -> syn::Result<ActivityMethod> {
|
|
61
|
+
let attributes = extract_activity_attributes(method.attrs.as_slice())?;
|
|
62
|
+
let is_async = method.sig.asyncness.is_some();
|
|
63
|
+
|
|
64
|
+
// Determine if static (no self receiver) or instance (Arc<Self>)
|
|
65
|
+
let is_static = match method.sig.inputs.first() {
|
|
66
|
+
Some(FnArg::Receiver(receiver)) => {
|
|
67
|
+
if receiver.colon_token.is_some() {
|
|
68
|
+
validate_arc_self_type(&receiver.ty)?;
|
|
69
|
+
false
|
|
70
|
+
} else {
|
|
71
|
+
return Err(syn::Error::new_spanned(
|
|
72
|
+
receiver,
|
|
73
|
+
"Activity methods with instance state must use `self: Arc<Self>` as the \
|
|
74
|
+
receiver, not `self`, `&self`, or `&mut self`",
|
|
75
|
+
));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
Some(FnArg::Typed(_)) | None => true,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
let input_types = extract_input_types(&method.sig)?;
|
|
82
|
+
let output_type = extract_output_type(&method.sig);
|
|
83
|
+
|
|
84
|
+
Ok(ActivityMethod {
|
|
85
|
+
method: method.clone(),
|
|
86
|
+
attributes,
|
|
87
|
+
is_async,
|
|
88
|
+
is_static,
|
|
89
|
+
input_types,
|
|
90
|
+
output_type,
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
fn extract_activity_attributes(attrs: &[Attribute]) -> syn::Result<ActivityAttributes> {
|
|
95
|
+
let mut activity_attributes = ActivityAttributes::default();
|
|
96
|
+
|
|
97
|
+
for attr in attrs {
|
|
98
|
+
if attr.path().is_ident("activity") && attr.meta.require_list().is_ok() {
|
|
99
|
+
attr.parse_nested_meta(|meta| {
|
|
100
|
+
if meta.path.is_ident("name") {
|
|
101
|
+
let value = meta.value()?;
|
|
102
|
+
let expr: syn::Expr = value.parse()?;
|
|
103
|
+
activity_attributes.name_override = Some(expr);
|
|
104
|
+
Ok(())
|
|
105
|
+
} else {
|
|
106
|
+
Err(meta.error("unsupported activity attribute"))
|
|
107
|
+
}
|
|
108
|
+
})?;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
Ok(activity_attributes)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fn validate_arc_self_type(ty: &Type) -> syn::Result<()> {
|
|
116
|
+
let expected: Type = syn::parse_quote!(Arc<Self>);
|
|
117
|
+
|
|
118
|
+
if let (Type::Path(actual_path), Type::Path(expected_path)) = (ty, &expected)
|
|
119
|
+
&& let (Some(actual_seg), Some(expected_seg)) = (
|
|
120
|
+
actual_path.path.segments.last(),
|
|
121
|
+
expected_path.path.segments.last(),
|
|
122
|
+
)
|
|
123
|
+
&& actual_seg == expected_seg
|
|
124
|
+
{
|
|
125
|
+
return Ok(());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Err(syn::Error::new_spanned(
|
|
129
|
+
ty,
|
|
130
|
+
"Instance activity methods must use `self: Arc<Self>` as the receiver type",
|
|
131
|
+
))
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
fn extract_input_types(sig: &syn::Signature) -> syn::Result<Vec<Type>> {
|
|
135
|
+
let mut found_ctx = false;
|
|
136
|
+
let mut types = Vec::new();
|
|
137
|
+
for arg in &sig.inputs {
|
|
138
|
+
if let FnArg::Typed(pat_type) = arg {
|
|
139
|
+
if found_ctx {
|
|
140
|
+
types.push((*pat_type.ty).clone());
|
|
141
|
+
} else if let Type::Path(type_path) = &*pat_type.ty
|
|
142
|
+
&& type_path
|
|
143
|
+
.path
|
|
144
|
+
.segments
|
|
145
|
+
.last()
|
|
146
|
+
.map(|s| s.ident == "ActivityContext")
|
|
147
|
+
.unwrap_or(false)
|
|
148
|
+
{
|
|
149
|
+
found_ctx = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if !found_ctx {
|
|
154
|
+
return Err(syn::Error::new(
|
|
155
|
+
sig.inputs.span(),
|
|
156
|
+
"Activity functions must have an ActivityContext parameter as either the first \
|
|
157
|
+
parameter, or the second after `self: Arc<Self>`.",
|
|
158
|
+
));
|
|
159
|
+
}
|
|
160
|
+
if types.len() > 6 {
|
|
161
|
+
return Err(syn::Error::new(
|
|
162
|
+
sig.inputs.span(),
|
|
163
|
+
"Activity functions support at most 6 input parameters (after ActivityContext).",
|
|
164
|
+
));
|
|
165
|
+
}
|
|
166
|
+
Ok(types)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fn extract_output_type(sig: &syn::Signature) -> Option<Type> {
|
|
170
|
+
match &sig.output {
|
|
171
|
+
ReturnType::Type(_, ty) => {
|
|
172
|
+
// Extract T from Result<T, ActivityError>
|
|
173
|
+
if let Type::Path(TypePath { path, .. }) = &**ty
|
|
174
|
+
&& let Some(segment) = path.segments.last()
|
|
175
|
+
&& segment.ident == "Result"
|
|
176
|
+
&& let syn::PathArguments::AngleBracketed(args) = &segment.arguments
|
|
177
|
+
&& let Some(syn::GenericArgument::Type(output_ty)) = args.args.first()
|
|
178
|
+
{
|
|
179
|
+
return Some(output_ty.clone());
|
|
180
|
+
}
|
|
181
|
+
// If it's not a Result type, assume it returns the type directly
|
|
182
|
+
Some((**ty).clone())
|
|
183
|
+
}
|
|
184
|
+
ReturnType::Default => None,
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/// Returns the token stream for the `Input` associated type given the list of input types.
|
|
189
|
+
fn multi_args_input_type(types: &[Type]) -> TokenStream2 {
|
|
190
|
+
match types.len() {
|
|
191
|
+
0 => quote! { () },
|
|
192
|
+
1 => {
|
|
193
|
+
let t = &types[0];
|
|
194
|
+
quote! { #t }
|
|
195
|
+
}
|
|
196
|
+
n => {
|
|
197
|
+
let multi_args = format_ident!("MultiArgs{}", n);
|
|
198
|
+
let types = types.iter();
|
|
199
|
+
quote! { ::temporalio_common::data_converters::#multi_args<#(#types),*> }
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/// Returns the destructuring statement for multi-arg input, or nothing for 0/1 args.
|
|
205
|
+
fn multi_args_destructure(types: &[Type]) -> TokenStream2 {
|
|
206
|
+
let n = types.len();
|
|
207
|
+
if n <= 1 {
|
|
208
|
+
return quote! {};
|
|
209
|
+
}
|
|
210
|
+
let multi_args = format_ident!("MultiArgs{}", n);
|
|
211
|
+
let idents = multi_args_idents(n);
|
|
212
|
+
quote! {
|
|
213
|
+
let ::temporalio_common::data_converters::#multi_args(#(#idents),*) = input;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// Returns identifiers `__arg0`, `__arg1`, ... for N arguments.
|
|
218
|
+
/// For single-arg, returns `input` to preserve backward compatibility.
|
|
219
|
+
fn multi_args_idents(n: usize) -> Vec<syn::Ident> {
|
|
220
|
+
if n == 1 {
|
|
221
|
+
vec![format_ident!("input")]
|
|
222
|
+
} else {
|
|
223
|
+
(0..n).map(|i| format_ident!("__arg{}", i)).collect()
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
impl ActivitiesDefinition {
|
|
228
|
+
pub(crate) fn codegen(&self) -> TokenStream {
|
|
229
|
+
let impl_type = &self.impl_block.self_ty;
|
|
230
|
+
let impl_type_name = type_name_string(impl_type);
|
|
231
|
+
let module_name = type_to_snake_case(impl_type);
|
|
232
|
+
let module_ident = format_ident!("{}", module_name);
|
|
233
|
+
|
|
234
|
+
// Generate the original impl block with:
|
|
235
|
+
// - #[activity] attributes stripped
|
|
236
|
+
// - Activity methods renamed with __ prefix
|
|
237
|
+
let mut cleaned_impl = self.impl_block.clone();
|
|
238
|
+
for item in &mut cleaned_impl.items {
|
|
239
|
+
if let ImplItem::Fn(method) = item {
|
|
240
|
+
let is_activity = method
|
|
241
|
+
.attrs
|
|
242
|
+
.iter()
|
|
243
|
+
.any(|attr| attr.path().is_ident("activity"));
|
|
244
|
+
|
|
245
|
+
method
|
|
246
|
+
.attrs
|
|
247
|
+
.retain(|attr| !attr.path().is_ident("activity"));
|
|
248
|
+
|
|
249
|
+
// Rename activity methods with __ prefix
|
|
250
|
+
if is_activity {
|
|
251
|
+
let new_name = format_ident!("__{}", method.sig.ident);
|
|
252
|
+
method.sig.ident = new_name;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Generate marker structs (inside module, no external references)
|
|
258
|
+
let activity_structs: Vec<_> = self
|
|
259
|
+
.activities
|
|
260
|
+
.iter()
|
|
261
|
+
.map(|act| generate_marker_struct(&act.method))
|
|
262
|
+
.collect();
|
|
263
|
+
|
|
264
|
+
// Generate consts in impl block pointing to marker structs
|
|
265
|
+
let activity_consts: Vec<_> = self
|
|
266
|
+
.activities
|
|
267
|
+
.iter()
|
|
268
|
+
.map(|act| {
|
|
269
|
+
let visibility = &act.method.vis;
|
|
270
|
+
let method_ident = &act.method.sig.ident;
|
|
271
|
+
let struct_name = method_name_to_pascal_case(&act.method.sig.ident);
|
|
272
|
+
let struct_ident = format_ident!("{}", struct_name);
|
|
273
|
+
let span = act.method.span();
|
|
274
|
+
let allow_attrs = extract_allow_attrs(&act.method.attrs);
|
|
275
|
+
quote_spanned! { span=>
|
|
276
|
+
#[allow(non_upper_case_globals)]
|
|
277
|
+
#(#allow_attrs)*
|
|
278
|
+
#visibility const #method_ident: #module_ident::#struct_ident = #module_ident::#struct_ident;
|
|
279
|
+
}
|
|
280
|
+
})
|
|
281
|
+
.collect();
|
|
282
|
+
|
|
283
|
+
// Generate run methods on marker structs (outside module to reference impl_type)
|
|
284
|
+
let run_impls: Vec<_> = self
|
|
285
|
+
.activities
|
|
286
|
+
.iter()
|
|
287
|
+
.map(|act| self.generate_run_impl(act, impl_type, &module_ident))
|
|
288
|
+
.collect();
|
|
289
|
+
|
|
290
|
+
// Generate ActivityDefinition and ExecutableActivity impls (outside module)
|
|
291
|
+
let activity_impls: Vec<_> = self
|
|
292
|
+
.activities
|
|
293
|
+
.iter()
|
|
294
|
+
.map(|act| {
|
|
295
|
+
self.generate_activity_definition_impl(
|
|
296
|
+
act,
|
|
297
|
+
impl_type,
|
|
298
|
+
&impl_type_name,
|
|
299
|
+
&module_ident,
|
|
300
|
+
)
|
|
301
|
+
})
|
|
302
|
+
.collect();
|
|
303
|
+
|
|
304
|
+
let implementer_impl = self.generate_activity_implementer_impl(impl_type, &module_ident);
|
|
305
|
+
|
|
306
|
+
let has_only_static = if self.activities.iter().all(|a| a.is_static) {
|
|
307
|
+
quote! {
|
|
308
|
+
impl ::temporalio_sdk::activities::HasOnlyStaticMethods for #impl_type {}
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
quote! {}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// Generate impl block with consts
|
|
315
|
+
let const_impl = quote! {
|
|
316
|
+
impl #impl_type {
|
|
317
|
+
#(#activity_consts)*
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
let output = quote! {
|
|
322
|
+
#cleaned_impl
|
|
323
|
+
|
|
324
|
+
#const_impl
|
|
325
|
+
|
|
326
|
+
// Module contains only the marker structs (no use super::*)
|
|
327
|
+
mod #module_ident {
|
|
328
|
+
#(#activity_structs)*
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Run methods, trait impls are outside the module
|
|
332
|
+
#(#run_impls)*
|
|
333
|
+
|
|
334
|
+
#(#activity_impls)*
|
|
335
|
+
|
|
336
|
+
#implementer_impl
|
|
337
|
+
|
|
338
|
+
#has_only_static
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
output.into()
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
fn generate_run_impl(
|
|
345
|
+
&self,
|
|
346
|
+
activity: &ActivityMethod,
|
|
347
|
+
impl_type: &Type,
|
|
348
|
+
module_ident: &syn::Ident,
|
|
349
|
+
) -> TokenStream2 {
|
|
350
|
+
let struct_name = method_name_to_pascal_case(&activity.method.sig.ident);
|
|
351
|
+
let struct_ident = format_ident!("{}", struct_name);
|
|
352
|
+
let prefixed_method = format_ident!("__{}", activity.method.sig.ident);
|
|
353
|
+
|
|
354
|
+
let input_type = multi_args_input_type(&activity.input_types);
|
|
355
|
+
let output_type = activity
|
|
356
|
+
.output_type
|
|
357
|
+
.as_ref()
|
|
358
|
+
.map(|t| quote! { #t })
|
|
359
|
+
.unwrap_or(quote! { () });
|
|
360
|
+
|
|
361
|
+
let has_input = !activity.input_types.is_empty();
|
|
362
|
+
|
|
363
|
+
// Build the parameters and call based on static vs instance and input
|
|
364
|
+
let (params, method_call) = if activity.is_static {
|
|
365
|
+
let params = if has_input {
|
|
366
|
+
quote! { self, ctx: ::temporalio_sdk::activities::ActivityContext, input: #input_type }
|
|
367
|
+
} else {
|
|
368
|
+
quote! { self, ctx: ::temporalio_sdk::activities::ActivityContext }
|
|
369
|
+
};
|
|
370
|
+
let call = if has_input {
|
|
371
|
+
let destructure = multi_args_destructure(&activity.input_types);
|
|
372
|
+
let arg_idents = multi_args_idents(activity.input_types.len());
|
|
373
|
+
quote! {
|
|
374
|
+
#destructure
|
|
375
|
+
#impl_type::#prefixed_method(ctx, #(#arg_idents),*)
|
|
376
|
+
}
|
|
377
|
+
} else {
|
|
378
|
+
quote! { #impl_type::#prefixed_method(ctx) }
|
|
379
|
+
};
|
|
380
|
+
(params, call)
|
|
381
|
+
} else {
|
|
382
|
+
let params = if has_input {
|
|
383
|
+
quote! { self, instance: ::std::sync::Arc<#impl_type>, ctx: ::temporalio_sdk::activities::ActivityContext, input: #input_type }
|
|
384
|
+
} else {
|
|
385
|
+
quote! { self, instance: ::std::sync::Arc<#impl_type>, ctx: ::temporalio_sdk::activities::ActivityContext }
|
|
386
|
+
};
|
|
387
|
+
let call = if has_input {
|
|
388
|
+
let destructure = multi_args_destructure(&activity.input_types);
|
|
389
|
+
let arg_idents = multi_args_idents(activity.input_types.len());
|
|
390
|
+
quote! {
|
|
391
|
+
#destructure
|
|
392
|
+
#impl_type::#prefixed_method(instance, ctx, #(#arg_idents),*)
|
|
393
|
+
}
|
|
394
|
+
} else {
|
|
395
|
+
quote! { #impl_type::#prefixed_method(instance, ctx) }
|
|
396
|
+
};
|
|
397
|
+
(params, call)
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
let return_type =
|
|
401
|
+
quote! { Result<#output_type, ::temporalio_sdk::activities::ActivityError> };
|
|
402
|
+
|
|
403
|
+
// If the method returns void (no return type), wrap with Ok(())
|
|
404
|
+
let result_wrapper = if activity.output_type.is_none() {
|
|
405
|
+
quote! { ; Ok(()) }
|
|
406
|
+
} else {
|
|
407
|
+
quote! {}
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
// Common methods for all marker structs
|
|
411
|
+
let common_methods = quote! {
|
|
412
|
+
/// Returns the activity name (delegates to ActivityDefinition::name())
|
|
413
|
+
pub fn name(&self) -> &'static str {
|
|
414
|
+
<Self as ::temporalio_common::ActivityDefinition>::name()
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
if activity.is_async {
|
|
419
|
+
quote! {
|
|
420
|
+
impl #module_ident::#struct_ident {
|
|
421
|
+
#common_methods
|
|
422
|
+
|
|
423
|
+
pub async fn run(#params) -> #return_type {
|
|
424
|
+
#method_call.await #result_wrapper
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
} else {
|
|
429
|
+
quote! {
|
|
430
|
+
impl #module_ident::#struct_ident {
|
|
431
|
+
#common_methods
|
|
432
|
+
|
|
433
|
+
pub fn run(#params) -> #return_type {
|
|
434
|
+
#method_call #result_wrapper
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
fn generate_activity_definition_impl(
|
|
442
|
+
&self,
|
|
443
|
+
activity: &ActivityMethod,
|
|
444
|
+
impl_type: &Type,
|
|
445
|
+
impl_type_name: &str,
|
|
446
|
+
module_ident: &syn::Ident,
|
|
447
|
+
) -> TokenStream2 {
|
|
448
|
+
let struct_name = method_name_to_pascal_case(&activity.method.sig.ident);
|
|
449
|
+
let struct_ident = format_ident!("{}", struct_name);
|
|
450
|
+
let prefixed_method = format_ident!("__{}", activity.method.sig.ident);
|
|
451
|
+
|
|
452
|
+
let input_type = multi_args_input_type(&activity.input_types);
|
|
453
|
+
let output_type = &activity
|
|
454
|
+
.output_type
|
|
455
|
+
.as_ref()
|
|
456
|
+
.map(|t| quote! { #t })
|
|
457
|
+
.unwrap_or(quote! { () });
|
|
458
|
+
|
|
459
|
+
let has_input = !activity.input_types.is_empty();
|
|
460
|
+
|
|
461
|
+
let activity_name = if let Some(ref name_expr) = activity.attributes.name_override {
|
|
462
|
+
quote! { #name_expr }
|
|
463
|
+
} else {
|
|
464
|
+
let default_name = format!("{}::{}", impl_type_name, activity.method.sig.ident);
|
|
465
|
+
quote! { #default_name }
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
let receiver_pattern = if activity.is_static {
|
|
469
|
+
quote! { _receiver }
|
|
470
|
+
} else {
|
|
471
|
+
quote! { receiver }
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
let method_call = if has_input {
|
|
475
|
+
let destructure = multi_args_destructure(&activity.input_types);
|
|
476
|
+
let arg_idents = multi_args_idents(activity.input_types.len());
|
|
477
|
+
if activity.is_static {
|
|
478
|
+
quote! {
|
|
479
|
+
#destructure
|
|
480
|
+
#impl_type::#prefixed_method(ctx, #(#arg_idents),*)
|
|
481
|
+
}
|
|
482
|
+
} else {
|
|
483
|
+
quote! {
|
|
484
|
+
#destructure
|
|
485
|
+
#impl_type::#prefixed_method(receiver.unwrap(), ctx, #(#arg_idents),*)
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
} else if activity.is_static {
|
|
489
|
+
quote! { #impl_type::#prefixed_method(ctx) }
|
|
490
|
+
} else {
|
|
491
|
+
quote! { #impl_type::#prefixed_method(receiver.unwrap(), ctx) }
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
let input_param = if has_input {
|
|
495
|
+
quote! { input: Self::Input, }
|
|
496
|
+
} else {
|
|
497
|
+
quote! { _input: Self::Input, }
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
let result_returner = if activity.output_type.is_none() {
|
|
501
|
+
quote! {; Ok(()) }
|
|
502
|
+
} else {
|
|
503
|
+
quote! {}
|
|
504
|
+
};
|
|
505
|
+
let execute_body = if activity.is_async {
|
|
506
|
+
quote! {
|
|
507
|
+
async move { #method_call.await #result_returner }.boxed()
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
quote! {
|
|
511
|
+
tokio::task::spawn_blocking(move || { #method_call #result_returner })
|
|
512
|
+
.map(|jh| match jh {
|
|
513
|
+
Err(err) => Err(::temporalio_sdk::activities::ActivityError::from(err)),
|
|
514
|
+
Ok(v) => v,
|
|
515
|
+
})
|
|
516
|
+
.boxed()
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
quote! {
|
|
521
|
+
impl ::temporalio_common::ActivityDefinition for #module_ident::#struct_ident {
|
|
522
|
+
type Input = #input_type;
|
|
523
|
+
type Output = #output_type;
|
|
524
|
+
|
|
525
|
+
fn name() -> &'static str
|
|
526
|
+
where
|
|
527
|
+
Self: Sized,
|
|
528
|
+
{
|
|
529
|
+
#activity_name
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
impl ::temporalio_sdk::activities::ExecutableActivity for #module_ident::#struct_ident {
|
|
534
|
+
type Implementer = #impl_type;
|
|
535
|
+
|
|
536
|
+
fn execute(
|
|
537
|
+
#receiver_pattern: Option<::std::sync::Arc<Self::Implementer>>,
|
|
538
|
+
ctx: ::temporalio_sdk::activities::ActivityContext,
|
|
539
|
+
#input_param
|
|
540
|
+
) -> ::futures::future::BoxFuture<'static,
|
|
541
|
+
Result<Self::Output, ::temporalio_sdk::activities::ActivityError>>
|
|
542
|
+
{
|
|
543
|
+
use ::futures::FutureExt;
|
|
544
|
+
|
|
545
|
+
#execute_body
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
fn generate_activity_implementer_impl(
|
|
552
|
+
&self,
|
|
553
|
+
impl_type: &Type,
|
|
554
|
+
module_ident: &syn::Ident,
|
|
555
|
+
) -> TokenStream2 {
|
|
556
|
+
let instance_activities: Vec<_> = self
|
|
557
|
+
.activities
|
|
558
|
+
.iter()
|
|
559
|
+
.map(|a| {
|
|
560
|
+
let struct_name = method_name_to_pascal_case(&a.method.sig.ident);
|
|
561
|
+
let struct_ident = format_ident!("{}", struct_name);
|
|
562
|
+
quote! {
|
|
563
|
+
defs.register_activity::<#module_ident::#struct_ident>(self.clone());
|
|
564
|
+
}
|
|
565
|
+
})
|
|
566
|
+
.collect();
|
|
567
|
+
|
|
568
|
+
let register_instance_body = if instance_activities.is_empty() {
|
|
569
|
+
quote! {}
|
|
570
|
+
} else {
|
|
571
|
+
quote! { #(#instance_activities)* }
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
quote! {
|
|
575
|
+
impl ::temporalio_sdk::activities::ActivityImplementer for #impl_type {
|
|
576
|
+
fn register_all(
|
|
577
|
+
self: ::std::sync::Arc<Self>,
|
|
578
|
+
defs: &mut ::temporalio_sdk::activities::ActivityDefinitions,
|
|
579
|
+
) {
|
|
580
|
+
#register_instance_body
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|