@temporalio/core-bridge 0.17.2 → 0.18.0
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 +339 -226
- package/Cargo.toml +7 -3
- package/common.js +50 -0
- package/index.d.ts +7 -0
- package/index.js +12 -0
- package/package.json +7 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/{index.node → releases/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/scripts/build.js +10 -50
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/Cargo.toml +1 -88
- package/sdk-core/README.md +30 -6
- package/sdk-core/bridge-ffi/Cargo.toml +24 -0
- package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- package/sdk-core/bridge-ffi/build.rs +25 -0
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
- package/sdk-core/bridge-ffi/src/lib.rs +829 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
- package/sdk-core/client/Cargo.toml +32 -0
- package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
- package/sdk-core/client/src/metrics.rs +89 -0
- package/sdk-core/client/src/mocks.rs +167 -0
- package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
- package/sdk-core/core/Cargo.toml +96 -0
- package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
- package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
- package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
- package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
- package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
- package/sdk-core/{src → core/src}/core_tests/queries.rs +45 -52
- package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
- package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
- package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
- package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +264 -286
- package/sdk-core/core/src/lib.rs +374 -0
- package/sdk-core/{src → core/src}/log_export.rs +3 -27
- package/sdk-core/core/src/pending_activations.rs +162 -0
- package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
- package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
- package/sdk-core/core/src/protosext/mod.rs +396 -0
- package/sdk-core/core/src/replay/mod.rs +210 -0
- package/sdk-core/core/src/retry_logic.rs +144 -0
- package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
- package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
- package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
- package/sdk-core/{src → core/src}/test_help/mod.rs +34 -73
- package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
- package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
- package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
- package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
- package/sdk-core/{src → core/src}/worker/mod.rs +305 -195
- package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
- package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
- package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
- package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
- package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
- package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
- package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
- package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
- package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
- package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
- package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
- package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
- package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
- package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
- package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
- package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
- package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
- package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +344 -160
- package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +297 -81
- package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
- package/sdk-core/{src → core-api/src}/errors.rs +42 -90
- package/sdk-core/core-api/src/lib.rs +158 -0
- package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
- package/sdk-core/etc/deps.svg +156 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
- package/sdk-core/histories/fail_wf_task.bin +0 -0
- package/sdk-core/histories/timer_workflow_history.bin +0 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
- package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
- package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
- package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
- package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
- package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
- package/sdk-core/sdk/Cargo.toml +32 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
- package/sdk-core/sdk/src/lib.rs +699 -0
- package/sdk-core/sdk/src/payload_converter.rs +11 -0
- package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
- package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
- package/sdk-core/sdk-core-protos/build.rs +28 -6
- package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
- package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +594 -168
- package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +32 -0
- package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
- package/sdk-core/test-utils/src/histfetch.rs +28 -0
- package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
- package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
- package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
- package/sdk-core/tests/load_tests.rs +6 -6
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +24 -21
- package/src/errors.rs +8 -0
- package/src/lib.rs +323 -211
- package/sdk-core/protos/local/activity_result.proto +0 -46
- package/sdk-core/protos/local/activity_task.proto +0 -66
- package/sdk-core/src/core_tests/retry.rs +0 -147
- package/sdk-core/src/lib.rs +0 -403
- package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
- package/sdk-core/src/pending_activations.rs +0 -249
- package/sdk-core/src/protosext/mod.rs +0 -160
- package/sdk-core/src/prototype_rust_sdk.rs +0 -412
- package/sdk-core/src/task_token.rs +0 -20
- package/sdk-core/src/test_help/history_info.rs +0 -158
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
[package]
|
|
2
|
-
name = "
|
|
2
|
+
name = "temporal-sdk-core-api"
|
|
3
3
|
version = "0.1.0"
|
|
4
|
-
authors = ["Spencer Judge <spencer@temporal.io>"]
|
|
5
4
|
edition = "2021"
|
|
6
5
|
|
|
7
6
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
8
7
|
|
|
9
8
|
[dependencies]
|
|
9
|
+
anyhow = "1.0"
|
|
10
10
|
async-trait = "0.1"
|
|
11
|
-
|
|
12
|
-
futures = "0.3"
|
|
11
|
+
derive_builder = "0.10"
|
|
13
12
|
log = "0.4"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
prost-types = "0.9"
|
|
14
|
+
thiserror = "1.0"
|
|
15
|
+
tonic = "0.6"
|
|
17
16
|
|
|
18
17
|
[dependencies.temporal-sdk-core-protos]
|
|
19
18
|
path = "../sdk-core-protos"
|
|
20
19
|
version = "0.1"
|
|
20
|
+
|
|
21
|
+
[dependencies.temporal-client]
|
|
22
|
+
path = "../client"
|
|
23
|
+
version = "0.1"
|
|
@@ -1,45 +1,19 @@
|
|
|
1
1
|
//! Error types exposed by public APIs
|
|
2
2
|
|
|
3
|
-
use
|
|
3
|
+
use prost_types::TimestampOutOfSystemRangeError;
|
|
4
|
+
use temporal_client::GatewayInitError;
|
|
4
5
|
use temporal_sdk_core_protos::coresdk::{
|
|
5
|
-
activity_result::
|
|
6
|
+
activity_result::ActivityExecutionResult,
|
|
7
|
+
workflow_activation::remove_from_cache::EvictionReason,
|
|
8
|
+
workflow_completion::WorkflowActivationCompletion,
|
|
6
9
|
};
|
|
7
|
-
use tonic::codegen::http::uri::InvalidUri;
|
|
8
|
-
|
|
9
|
-
#[derive(Debug)]
|
|
10
|
-
pub(crate) struct WorkflowUpdateError {
|
|
11
|
-
/// Underlying workflow error
|
|
12
|
-
pub source: WFMachinesError,
|
|
13
|
-
/// The run id of the erring workflow
|
|
14
|
-
#[allow(dead_code)] // Useful in debug output
|
|
15
|
-
pub run_id: String,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
impl From<WorkflowMissingError> for WorkflowUpdateError {
|
|
19
|
-
fn from(wme: WorkflowMissingError) -> Self {
|
|
20
|
-
Self {
|
|
21
|
-
source: WFMachinesError::Fatal("Workflow machines missing".to_string()),
|
|
22
|
-
run_id: wme.run_id,
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/// The workflow machines were expected to be in the cache but were not
|
|
28
|
-
#[derive(Debug)]
|
|
29
|
-
pub(crate) struct WorkflowMissingError {
|
|
30
|
-
/// The run id of the erring workflow
|
|
31
|
-
pub run_id: String,
|
|
32
|
-
}
|
|
33
10
|
|
|
34
11
|
/// Errors thrown during initialization of [crate::Core]
|
|
35
12
|
#[derive(thiserror::Error, Debug)]
|
|
36
13
|
pub enum CoreInitError {
|
|
37
|
-
/// Invalid URI. Configuration error, fatal.
|
|
38
|
-
#[error("Invalid URI: {0:?}")]
|
|
39
|
-
InvalidUri(#[from] InvalidUri),
|
|
40
14
|
/// Server connection error. Crashing and restarting the worker is likely best.
|
|
41
15
|
#[error("Server connection error: {0:?}")]
|
|
42
|
-
|
|
16
|
+
GatewayInitError(#[from] GatewayInitError),
|
|
43
17
|
/// There was a problem initializing telemetry
|
|
44
18
|
#[error("Telemetry initialization error: {0:?}")]
|
|
45
19
|
TelemetryInitError(anyhow::Error),
|
|
@@ -67,15 +41,6 @@ pub enum PollWfError {
|
|
|
67
41
|
NoWorkerForQueue(String),
|
|
68
42
|
}
|
|
69
43
|
|
|
70
|
-
impl From<WorkerLookupErr> for PollWfError {
|
|
71
|
-
fn from(e: WorkerLookupErr) -> Self {
|
|
72
|
-
match e {
|
|
73
|
-
WorkerLookupErr::Shutdown(_) => Self::ShutDown,
|
|
74
|
-
WorkerLookupErr::NoWorker(s) => Self::NoWorkerForQueue(s),
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
44
|
/// Errors thrown by [crate::Core::poll_activity_task]
|
|
80
45
|
#[derive(thiserror::Error, Debug)]
|
|
81
46
|
pub enum PollActivityError {
|
|
@@ -92,15 +57,6 @@ pub enum PollActivityError {
|
|
|
92
57
|
NoWorkerForQueue(String),
|
|
93
58
|
}
|
|
94
59
|
|
|
95
|
-
impl From<WorkerLookupErr> for PollActivityError {
|
|
96
|
-
fn from(e: WorkerLookupErr) -> Self {
|
|
97
|
-
match e {
|
|
98
|
-
WorkerLookupErr::Shutdown(_) => Self::ShutDown,
|
|
99
|
-
WorkerLookupErr::NoWorker(s) => Self::NoWorkerForQueue(s),
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
60
|
/// Errors thrown by [crate::Core::complete_workflow_activation]
|
|
105
61
|
#[derive(thiserror::Error, Debug)]
|
|
106
62
|
#[allow(clippy::large_enum_variant)]
|
|
@@ -111,7 +67,7 @@ pub enum CompleteWfError {
|
|
|
111
67
|
/// Reason the completion was malformed
|
|
112
68
|
reason: String,
|
|
113
69
|
/// The completion, which may not be included to avoid unnecessary copies.
|
|
114
|
-
completion: Option<
|
|
70
|
+
completion: Option<WorkflowActivationCompletion>,
|
|
115
71
|
},
|
|
116
72
|
/// There is no worker registered for the queue being polled
|
|
117
73
|
#[error("No worker registered for queue: {0}")]
|
|
@@ -122,16 +78,6 @@ pub enum CompleteWfError {
|
|
|
122
78
|
TonicError(#[from] tonic::Status),
|
|
123
79
|
}
|
|
124
80
|
|
|
125
|
-
impl From<WorkerLookupErr> for CompleteWfError {
|
|
126
|
-
fn from(e: WorkerLookupErr) -> Self {
|
|
127
|
-
match e {
|
|
128
|
-
WorkerLookupErr::Shutdown(s) | WorkerLookupErr::NoWorker(s) => {
|
|
129
|
-
Self::NoWorkerForQueue(s)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
81
|
/// Errors thrown by [crate::Core::complete_activity_task]
|
|
136
82
|
#[derive(thiserror::Error, Debug)]
|
|
137
83
|
pub enum CompleteActivityError {
|
|
@@ -141,7 +87,7 @@ pub enum CompleteActivityError {
|
|
|
141
87
|
/// Reason the completion was malformed
|
|
142
88
|
reason: String,
|
|
143
89
|
/// The completion, which may not be included to avoid unnecessary copies.
|
|
144
|
-
completion: Option<
|
|
90
|
+
completion: Option<ActivityExecutionResult>,
|
|
145
91
|
},
|
|
146
92
|
/// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
|
|
147
93
|
/// errors, so lang should consider this fatal.
|
|
@@ -152,34 +98,6 @@ pub enum CompleteActivityError {
|
|
|
152
98
|
NoWorkerForQueue(String),
|
|
153
99
|
}
|
|
154
100
|
|
|
155
|
-
impl From<WorkerLookupErr> for CompleteActivityError {
|
|
156
|
-
fn from(e: WorkerLookupErr) -> Self {
|
|
157
|
-
match e {
|
|
158
|
-
WorkerLookupErr::Shutdown(s) | WorkerLookupErr::NoWorker(s) => {
|
|
159
|
-
Self::NoWorkerForQueue(s)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/// Errors thrown by [crate::Core::record_activity_heartbeat]
|
|
166
|
-
#[derive(thiserror::Error, Debug)]
|
|
167
|
-
pub enum ActivityHeartbeatError {
|
|
168
|
-
/// Heartbeat referenced an activity that we don't think exists. It may have completed already.
|
|
169
|
-
#[error("Heartbeat has been sent for activity that either completed or never started on this worker.")]
|
|
170
|
-
UnknownActivity,
|
|
171
|
-
/// There was no heartbeat timeout set for the activity, but one is required to heartbeat.
|
|
172
|
-
#[error("Heartbeat is only allowed on activities with heartbeat timeout.")]
|
|
173
|
-
HeartbeatTimeoutNotSet,
|
|
174
|
-
/// There was a set heartbeat timeout, but it was not parseable. A valid timeout is requried
|
|
175
|
-
/// to heartbeat.
|
|
176
|
-
#[error("Unable to parse activity heartbeat timeout.")]
|
|
177
|
-
InvalidHeartbeatTimeout,
|
|
178
|
-
/// Core is shutting down and thus new heartbeats are not accepted
|
|
179
|
-
#[error("New heartbeat requests are not accepted while shutting down")]
|
|
180
|
-
ShuttingDown,
|
|
181
|
-
}
|
|
182
|
-
|
|
183
101
|
/// Errors thrown by [crate::Core::register_worker]
|
|
184
102
|
#[derive(thiserror::Error, Debug)]
|
|
185
103
|
pub enum WorkerRegistrationError {
|
|
@@ -187,3 +105,37 @@ pub enum WorkerRegistrationError {
|
|
|
187
105
|
#[error("Worker already registered for queue: {0}")]
|
|
188
106
|
WorkerAlreadyRegisteredForQueue(String),
|
|
189
107
|
}
|
|
108
|
+
|
|
109
|
+
/// Errors thrown inside of workflow machines
|
|
110
|
+
#[derive(thiserror::Error, Debug)]
|
|
111
|
+
pub enum WFMachinesError {
|
|
112
|
+
#[error("Nondeterminism error: {0}")]
|
|
113
|
+
Nondeterminism(String),
|
|
114
|
+
#[error("Fatal error in workflow machines: {0}")]
|
|
115
|
+
Fatal(String),
|
|
116
|
+
|
|
117
|
+
#[error("Unrecoverable network error while fetching history: {0}")]
|
|
118
|
+
HistoryFetchingError(tonic::Status),
|
|
119
|
+
|
|
120
|
+
/// Should always be caught internally and turned into a workflow task failure
|
|
121
|
+
#[error("Unable to process partial event history because workflow is no longer cached.")]
|
|
122
|
+
CacheMiss,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
impl WFMachinesError {
|
|
126
|
+
pub fn evict_reason(&self) -> EvictionReason {
|
|
127
|
+
match self {
|
|
128
|
+
WFMachinesError::Nondeterminism(_) => EvictionReason::Nondeterminism,
|
|
129
|
+
WFMachinesError::Fatal(_) | WFMachinesError::HistoryFetchingError(_) => {
|
|
130
|
+
EvictionReason::Fatal
|
|
131
|
+
}
|
|
132
|
+
WFMachinesError::CacheMiss => EvictionReason::CacheMiss,
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
impl From<TimestampOutOfSystemRangeError> for WFMachinesError {
|
|
138
|
+
fn from(_: TimestampOutOfSystemRangeError) -> Self {
|
|
139
|
+
Self::Fatal("Could not decode timestamp".to_string())
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
pub mod errors;
|
|
2
|
+
pub mod worker;
|
|
3
|
+
|
|
4
|
+
use crate::{
|
|
5
|
+
errors::{
|
|
6
|
+
CompleteActivityError, CompleteWfError, PollActivityError, PollWfError,
|
|
7
|
+
WorkerRegistrationError,
|
|
8
|
+
},
|
|
9
|
+
worker::WorkerConfig,
|
|
10
|
+
};
|
|
11
|
+
use log::Level;
|
|
12
|
+
use std::{
|
|
13
|
+
sync::Arc,
|
|
14
|
+
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
15
|
+
};
|
|
16
|
+
use temporal_client::ServerGatewayApis;
|
|
17
|
+
use temporal_sdk_core_protos::coresdk::{
|
|
18
|
+
activity_task::ActivityTask, workflow_activation::WorkflowActivation,
|
|
19
|
+
workflow_completion::WorkflowActivationCompletion, ActivityHeartbeat, ActivityTaskCompletion,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/// This trait is the primary way by which language specific SDKs interact with the core SDK. It is
|
|
23
|
+
/// expected that only one instance of an implementation will exist for the lifetime of the
|
|
24
|
+
/// worker(s) using it.
|
|
25
|
+
#[async_trait::async_trait]
|
|
26
|
+
pub trait Core: Send + Sync {
|
|
27
|
+
/// Register a worker with core. Workers poll on a specific task queue, and when calling core's
|
|
28
|
+
/// poll functions, you must provide a task queue name. If there was already a worker registered
|
|
29
|
+
/// with the same task queue name, it will be shut down and a new one will be created.
|
|
30
|
+
fn register_worker(&self, config: WorkerConfig) -> Result<(), WorkerRegistrationError>;
|
|
31
|
+
|
|
32
|
+
/// Ask the core for some work, returning a [WorkflowActivation]. It is then the language SDK's
|
|
33
|
+
/// responsibility to call the appropriate workflow code with the provided inputs. Blocks
|
|
34
|
+
/// indefinitely until such work is available or [Core::shutdown] is called.
|
|
35
|
+
///
|
|
36
|
+
/// The returned activation is guaranteed to be for the same task queue / worker which was
|
|
37
|
+
/// provided as the `task_queue` argument.
|
|
38
|
+
///
|
|
39
|
+
/// It is important to understand that all activations must be responded to. There can only
|
|
40
|
+
/// be one outstanding activation for a particular run of a workflow at any time. If an
|
|
41
|
+
/// activation is not responded to, it will cause that workflow to become stuck forever.
|
|
42
|
+
///
|
|
43
|
+
/// Activations that contain only a `remove_from_cache` job should not cause the workflow code
|
|
44
|
+
/// to be invoked and may be responded to with an empty command list. Eviction jobs may also
|
|
45
|
+
/// appear with other jobs, but will always appear last in the job list. In this case it is
|
|
46
|
+
/// expected that the workflow code will be invoked, and the response produced as normal, but
|
|
47
|
+
/// the caller should evict the run after doing so.
|
|
48
|
+
///
|
|
49
|
+
/// It is rarely a good idea to call poll concurrently. It handles polling the server
|
|
50
|
+
/// concurrently internally.
|
|
51
|
+
///
|
|
52
|
+
/// TODO: Examples
|
|
53
|
+
async fn poll_workflow_activation(
|
|
54
|
+
&self,
|
|
55
|
+
task_queue: &str,
|
|
56
|
+
) -> Result<WorkflowActivation, PollWfError>;
|
|
57
|
+
|
|
58
|
+
/// Ask the core for some work, returning an [ActivityTask]. It is then the language SDK's
|
|
59
|
+
/// responsibility to call the appropriate activity code with the provided inputs. Blocks
|
|
60
|
+
/// indefinitely until such work is available or [Core::shutdown] is called.
|
|
61
|
+
///
|
|
62
|
+
/// The returned activation is guaranteed to be for the same task queue / worker which was
|
|
63
|
+
/// provided as the `task_queue` argument.
|
|
64
|
+
///
|
|
65
|
+
/// It is rarely a good idea to call poll concurrently. It handles polling the server
|
|
66
|
+
/// concurrently internally.
|
|
67
|
+
///
|
|
68
|
+
/// TODO: Examples
|
|
69
|
+
async fn poll_activity_task(&self, task_queue: &str)
|
|
70
|
+
-> Result<ActivityTask, PollActivityError>;
|
|
71
|
+
|
|
72
|
+
/// Tell the core that a workflow activation has completed. May be freely called concurrently.
|
|
73
|
+
async fn complete_workflow_activation(
|
|
74
|
+
&self,
|
|
75
|
+
completion: WorkflowActivationCompletion,
|
|
76
|
+
) -> Result<(), CompleteWfError>;
|
|
77
|
+
|
|
78
|
+
/// Tell the core that an activity has finished executing. May be freely called concurrently.
|
|
79
|
+
async fn complete_activity_task(
|
|
80
|
+
&self,
|
|
81
|
+
completion: ActivityTaskCompletion,
|
|
82
|
+
) -> Result<(), CompleteActivityError>;
|
|
83
|
+
|
|
84
|
+
/// Notify workflow that an activity is still alive. Long running activities that take longer
|
|
85
|
+
/// than `activity_heartbeat_timeout` to finish must call this function in order to report
|
|
86
|
+
/// progress, otherwise the activity will timeout and a new attempt will be scheduled.
|
|
87
|
+
///
|
|
88
|
+
/// The first heartbeat request will be sent immediately, subsequent rapid calls to this
|
|
89
|
+
/// function will result in heartbeat requests being aggregated and the last one received during
|
|
90
|
+
/// the aggregation period will be sent to the server, where that period is defined as half the
|
|
91
|
+
/// heartbeat timeout.
|
|
92
|
+
///
|
|
93
|
+
/// Unlike java/go SDKs we do not return cancellation status as part of heartbeat response and
|
|
94
|
+
/// instead send it as a separate activity task to the lang, decoupling heartbeat and
|
|
95
|
+
/// cancellation processing.
|
|
96
|
+
///
|
|
97
|
+
/// For now activity still need to send heartbeats if they want to receive cancellation
|
|
98
|
+
/// requests. In the future we will change this and will dispatch cancellations more
|
|
99
|
+
/// proactively. Note that this function does not block on the server call and returns
|
|
100
|
+
/// immediately. Underlying validation errors are swallowed and logged, this has been agreed to
|
|
101
|
+
/// be optimal behavior for the user as we don't want to break activity execution due to badly
|
|
102
|
+
/// configured heartbeat options.
|
|
103
|
+
fn record_activity_heartbeat(&self, details: ActivityHeartbeat);
|
|
104
|
+
|
|
105
|
+
/// Request that a workflow be evicted by its run id. This will generate a workflow activation
|
|
106
|
+
/// with the eviction job inside it to be eventually returned by
|
|
107
|
+
/// [Core::poll_workflow_activation]. If the workflow had any existing outstanding activations,
|
|
108
|
+
/// such activations are invalidated and subsequent completions of them will do nothing and log
|
|
109
|
+
/// a warning.
|
|
110
|
+
fn request_workflow_eviction(&self, task_queue: &str, run_id: &str);
|
|
111
|
+
|
|
112
|
+
/// Returns core's instance of the [ServerGatewayApis] implementor it is using.
|
|
113
|
+
fn server_gateway(&self) -> Arc<dyn ServerGatewayApis + Send + Sync>;
|
|
114
|
+
|
|
115
|
+
/// Initiates async shutdown procedure, eventually ceases all polling of the server and shuts
|
|
116
|
+
/// down all registered workers. [Core::poll_workflow_activation] should be called until it
|
|
117
|
+
/// returns [PollWfError::ShutDown] to ensure that any workflows which are still undergoing
|
|
118
|
+
/// replay have an opportunity to finish. This means that the lang sdk will need to call
|
|
119
|
+
/// [Core::complete_workflow_activation] for those workflows until they are done. At that point,
|
|
120
|
+
/// the lang SDK can end the process, or drop the [Core] instance, which will close the
|
|
121
|
+
/// connection.
|
|
122
|
+
async fn shutdown(&self);
|
|
123
|
+
|
|
124
|
+
/// Shut down a specific worker. Will cease all polling on the task queue and future attempts
|
|
125
|
+
/// to poll that queue will return [PollWfError::NoWorkerForQueue].
|
|
126
|
+
async fn shutdown_worker(&self, task_queue: &str);
|
|
127
|
+
|
|
128
|
+
/// Core buffers logs that should be shuttled over to lang so that they may be rendered with
|
|
129
|
+
/// the user's desired logging library. Use this function to grab the most recent buffered logs
|
|
130
|
+
/// since the last time it was called. A fixed number of such logs are retained at maximum, with
|
|
131
|
+
/// the oldest being dropped when full.
|
|
132
|
+
///
|
|
133
|
+
/// Returns the list of logs from oldest to newest. Returns an empty vec if the feature is not
|
|
134
|
+
/// configured.
|
|
135
|
+
fn fetch_buffered_logs(&self) -> Vec<CoreLog>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// A log line (which ultimately came from a tracing event) exported from Core->Lang
|
|
139
|
+
#[derive(Debug)]
|
|
140
|
+
pub struct CoreLog {
|
|
141
|
+
/// Log message
|
|
142
|
+
pub message: String,
|
|
143
|
+
/// Time log was generated (not when it was exported to lang)
|
|
144
|
+
pub timestamp: SystemTime,
|
|
145
|
+
/// Message level
|
|
146
|
+
pub level: Level,
|
|
147
|
+
// KV pairs aren't meaningfully exposed yet to the log interface by tracing
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
impl CoreLog {
|
|
151
|
+
/// Return timestamp as ms since epoch
|
|
152
|
+
pub fn millis_since_epoch(&self) -> u128 {
|
|
153
|
+
self.timestamp
|
|
154
|
+
.duration_since(UNIX_EPOCH)
|
|
155
|
+
.unwrap_or(Duration::ZERO)
|
|
156
|
+
.as_millis()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
use std::time::Duration;
|
|
2
2
|
|
|
3
|
-
#[cfg(test)]
|
|
4
|
-
use crate::test_help::TEST_Q;
|
|
5
|
-
|
|
6
3
|
/// Defines per-worker configuration options
|
|
7
4
|
#[derive(Debug, Clone, derive_builder::Builder)]
|
|
8
5
|
#[builder(setter(into), build_fn(validate = "Self::validate"))]
|
|
6
|
+
#[non_exhaustive]
|
|
9
7
|
// TODO: per-second queue limits
|
|
10
8
|
pub struct WorkerConfig {
|
|
11
9
|
/// What task queue will this worker poll from? This task queue name will be used for both
|
|
@@ -23,10 +21,13 @@ pub struct WorkerConfig {
|
|
|
23
21
|
/// "outstanding" until all activations it requires have been completed.
|
|
24
22
|
#[builder(default = "100")]
|
|
25
23
|
pub max_outstanding_workflow_tasks: usize,
|
|
26
|
-
/// The maximum
|
|
27
|
-
/// time.
|
|
24
|
+
/// The maximum number of activity tasks that will ever be given to this worker concurrently
|
|
28
25
|
#[builder(default = "100")]
|
|
29
26
|
pub max_outstanding_activities: usize,
|
|
27
|
+
/// The maximum number of local activity tasks that will ever be given to this worker
|
|
28
|
+
/// concurrently
|
|
29
|
+
#[builder(default = "100")]
|
|
30
|
+
pub max_outstanding_local_activities: usize,
|
|
30
31
|
/// Maximum number of concurrent poll workflow task requests we will perform at a time on this
|
|
31
32
|
/// worker's task queue. See also [WorkerConfig::nonsticky_to_sticky_poll_ratio]. Must be at
|
|
32
33
|
/// least 1.
|
|
@@ -64,6 +65,18 @@ pub struct WorkerConfig {
|
|
|
64
65
|
pub default_heartbeat_throttle_interval: Duration,
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
impl WorkerConfig {
|
|
69
|
+
pub fn max_nonsticky_polls(&self) -> usize {
|
|
70
|
+
((self.max_concurrent_wft_polls as f32 * self.nonsticky_to_sticky_poll_ratio) as usize)
|
|
71
|
+
.max(1)
|
|
72
|
+
}
|
|
73
|
+
pub fn max_sticky_polls(&self) -> usize {
|
|
74
|
+
self.max_concurrent_wft_polls
|
|
75
|
+
.saturating_sub(self.max_nonsticky_polls())
|
|
76
|
+
.max(1)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
impl WorkerConfigBuilder {
|
|
68
81
|
fn validate(&self) -> Result<(), String> {
|
|
69
82
|
if self.max_concurrent_wft_polls == Some(0) {
|
|
@@ -72,21 +85,3 @@ impl WorkerConfigBuilder {
|
|
|
72
85
|
Ok(())
|
|
73
86
|
}
|
|
74
87
|
}
|
|
75
|
-
|
|
76
|
-
impl WorkerConfig {
|
|
77
|
-
#[cfg(test)]
|
|
78
|
-
pub fn default_test_q() -> Self {
|
|
79
|
-
WorkerConfigBuilder::default()
|
|
80
|
-
.task_queue(TEST_Q)
|
|
81
|
-
.build()
|
|
82
|
-
.unwrap()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
#[cfg(test)]
|
|
86
|
-
pub fn default(queue: &str) -> Self {
|
|
87
|
-
WorkerConfigBuilder::default()
|
|
88
|
-
.task_queue(queue)
|
|
89
|
-
.build()
|
|
90
|
-
.unwrap()
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
3
|
+
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
4
|
+
<!-- Generated by graphviz version 2.50.0 (0)
|
|
5
|
+
-->
|
|
6
|
+
<!-- Pages: 1 -->
|
|
7
|
+
<svg width="421pt" height="404pt"
|
|
8
|
+
viewBox="0.00 0.00 420.50 404.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
9
|
+
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 400)">
|
|
10
|
+
<polygon fill="white" stroke="transparent" points="-4,4 -4,-400 416.5,-400 416.5,4 -4,4"/>
|
|
11
|
+
<!-- 0 -->
|
|
12
|
+
<g id="node1" class="node">
|
|
13
|
+
<title>0</title>
|
|
14
|
+
<polygon fill="none" stroke="black" points="248,-396 132,-396 132,-360 248,-360 248,-396"/>
|
|
15
|
+
<text text-anchor="middle" x="190" y="-374.3" font-family="Times,serif" font-size="14.00">temporal-sdk-core</text>
|
|
16
|
+
</g>
|
|
17
|
+
<!-- 1 -->
|
|
18
|
+
<g id="node2" class="node">
|
|
19
|
+
<title>1</title>
|
|
20
|
+
<polygon fill="none" stroke="black" points="58,-324 0,-324 0,-288 58,-288 58,-324"/>
|
|
21
|
+
<text text-anchor="middle" x="29" y="-302.3" font-family="Times,serif" font-size="14.00">rustfsm</text>
|
|
22
|
+
</g>
|
|
23
|
+
<!-- 0->1 -->
|
|
24
|
+
<g id="edge1" class="edge">
|
|
25
|
+
<title>0->1</title>
|
|
26
|
+
<path fill="none" stroke="black" d="M150.61,-359.88C125.27,-348.86 92.5,-334.61 67.36,-323.68"/>
|
|
27
|
+
<polygon fill="black" stroke="black" points="68.7,-320.44 58.13,-319.67 65.91,-326.86 68.7,-320.44"/>
|
|
28
|
+
</g>
|
|
29
|
+
<!-- 4 -->
|
|
30
|
+
<g id="node3" class="node">
|
|
31
|
+
<title>4</title>
|
|
32
|
+
<polygon fill="none" stroke="black" points="214,-108 114,-108 114,-72 214,-72 214,-108"/>
|
|
33
|
+
<text text-anchor="middle" x="164" y="-86.3" font-family="Times,serif" font-size="14.00">temporal-client</text>
|
|
34
|
+
</g>
|
|
35
|
+
<!-- 0->4 -->
|
|
36
|
+
<g id="edge2" class="edge">
|
|
37
|
+
<title>0->4</title>
|
|
38
|
+
<path fill="none" stroke="black" d="M181.7,-359.96C171.44,-325.92 157.74,-247.02 153,-180 151.87,-164.04 152.7,-160 153,-144 153.16,-135.58 153.46,-126.42 154.19,-118.12"/>
|
|
39
|
+
<polygon fill="black" stroke="black" points="157.67,-118.52 155.37,-108.18 150.71,-117.7 157.67,-118.52"/>
|
|
40
|
+
</g>
|
|
41
|
+
<!-- 0->4 -->
|
|
42
|
+
<g id="edge3" class="edge">
|
|
43
|
+
<title>0->4</title>
|
|
44
|
+
<path fill="none" stroke="blue" d="M191.8,-359.96C189.44,-325.92 175.74,-247.02 171,-180 169.87,-164.04 170.7,-160 171,-144 171.16,-135.68 171.45,-126.63 171.37,-118.4"/>
|
|
45
|
+
<polygon fill="blue" stroke="blue" points="174.86,-118.05 171.01,-108.18 167.87,-118.3 174.86,-118.05"/>
|
|
46
|
+
</g>
|
|
47
|
+
<!-- 5 -->
|
|
48
|
+
<g id="node4" class="node">
|
|
49
|
+
<title>5</title>
|
|
50
|
+
<polygon fill="none" stroke="black" points="319.5,-36 164.5,-36 164.5,0 319.5,0 319.5,-36"/>
|
|
51
|
+
<text text-anchor="middle" x="242" y="-14.3" font-family="Times,serif" font-size="14.00">temporal-sdk-core-protos</text>
|
|
52
|
+
</g>
|
|
53
|
+
<!-- 0->5 -->
|
|
54
|
+
<g id="edge6" class="edge">
|
|
55
|
+
<title>0->5</title>
|
|
56
|
+
<path fill="none" stroke="black" d="M165.88,-359.82C135.16,-335.73 86,-288.78 86,-235 86,-235 86,-235 86,-161 86,-120.55 78.76,-102.78 105,-72 118.09,-56.64 136.18,-45.72 154.93,-37.95"/>
|
|
57
|
+
<polygon fill="black" stroke="black" points="156.39,-41.14 164.46,-34.27 153.87,-34.6 156.39,-41.14"/>
|
|
58
|
+
</g>
|
|
59
|
+
<!-- 6 -->
|
|
60
|
+
<g id="node5" class="node">
|
|
61
|
+
<title>6</title>
|
|
62
|
+
<polygon fill="none" stroke="black" points="307.5,-180 170.5,-180 170.5,-144 307.5,-144 307.5,-180"/>
|
|
63
|
+
<text text-anchor="middle" x="239" y="-158.3" font-family="Times,serif" font-size="14.00">temporal-sdk-core-api</text>
|
|
64
|
+
</g>
|
|
65
|
+
<!-- 0->6 -->
|
|
66
|
+
<g id="edge5" class="edge">
|
|
67
|
+
<title>0->6</title>
|
|
68
|
+
<path fill="none" stroke="black" d="M193.8,-359.93C197.8,-342.01 204.29,-313.01 210,-288 217.68,-254.36 226.68,-215.68 232.6,-190.36"/>
|
|
69
|
+
<polygon fill="black" stroke="black" points="236.06,-190.92 234.93,-180.38 229.24,-189.32 236.06,-190.92"/>
|
|
70
|
+
</g>
|
|
71
|
+
<!-- 7 -->
|
|
72
|
+
<g id="node6" class="node">
|
|
73
|
+
<title>7</title>
|
|
74
|
+
<polygon fill="none" stroke="black" points="412.5,-252 323.5,-252 323.5,-216 412.5,-216 412.5,-252"/>
|
|
75
|
+
<text text-anchor="middle" x="368" y="-230.3" font-family="Times,serif" font-size="14.00">temporal-sdk</text>
|
|
76
|
+
</g>
|
|
77
|
+
<!-- 0->7 -->
|
|
78
|
+
<g id="edge4" class="edge">
|
|
79
|
+
<title>0->7</title>
|
|
80
|
+
<path fill="none" stroke="blue" d="M224.19,-359.83C242.9,-350.78 265.76,-338.54 284,-324 307.09,-305.6 328.26,-279.21 343.85,-259.94"/>
|
|
81
|
+
<polygon fill="blue" stroke="blue" points="346.58,-262.13 350.18,-252.17 341.15,-257.71 346.58,-262.13"/>
|
|
82
|
+
</g>
|
|
83
|
+
<!-- 8 -->
|
|
84
|
+
<g id="node7" class="node">
|
|
85
|
+
<title>8</title>
|
|
86
|
+
<polygon fill="none" stroke="black" points="283.5,-324 218.5,-324 218.5,-288 283.5,-288 283.5,-324"/>
|
|
87
|
+
<text text-anchor="middle" x="251" y="-302.3" font-family="Times,serif" font-size="14.00">test_utils</text>
|
|
88
|
+
</g>
|
|
89
|
+
<!-- 0->8 -->
|
|
90
|
+
<g id="edge7" class="edge">
|
|
91
|
+
<title>0->8</title>
|
|
92
|
+
<path fill="none" stroke="blue" d="M199.16,-359.7C205.68,-351.22 214.51,-340.86 223.1,-331.58"/>
|
|
93
|
+
<polygon fill="blue" stroke="blue" points="225.85,-333.77 230.2,-324.1 220.78,-328.95 225.85,-333.77"/>
|
|
94
|
+
</g>
|
|
95
|
+
<!-- 4->5 -->
|
|
96
|
+
<g id="edge8" class="edge">
|
|
97
|
+
<title>4->5</title>
|
|
98
|
+
<path fill="none" stroke="black" d="M183.28,-71.7C192.92,-63.05 204.73,-52.45 215.23,-43.03"/>
|
|
99
|
+
<polygon fill="black" stroke="black" points="217.84,-45.39 222.94,-36.1 213.16,-40.18 217.84,-45.39"/>
|
|
100
|
+
</g>
|
|
101
|
+
<!-- 6->4 -->
|
|
102
|
+
<g id="edge9" class="edge">
|
|
103
|
+
<title>6->4</title>
|
|
104
|
+
<path fill="none" stroke="black" d="M220.46,-143.7C211.2,-135.05 199.84,-124.45 189.74,-115.03"/>
|
|
105
|
+
<polygon fill="black" stroke="black" points="192.02,-112.37 182.33,-108.1 187.25,-117.49 192.02,-112.37"/>
|
|
106
|
+
</g>
|
|
107
|
+
<!-- 6->5 -->
|
|
108
|
+
<g id="edge10" class="edge">
|
|
109
|
+
<title>6->5</title>
|
|
110
|
+
<path fill="none" stroke="black" d="M239.36,-143.87C239.87,-119.67 240.81,-75.21 241.42,-46.39"/>
|
|
111
|
+
<polygon fill="black" stroke="black" points="244.92,-46.26 241.64,-36.19 237.93,-46.11 244.92,-46.26"/>
|
|
112
|
+
</g>
|
|
113
|
+
<!-- 7->0 -->
|
|
114
|
+
<g id="edge11" class="edge">
|
|
115
|
+
<title>7->0</title>
|
|
116
|
+
<path fill="none" stroke="black" d="M363.18,-252.17C352.26,-271.5 328.39,-302.97 302,-324 286.4,-336.43 267.42,-347.19 249.5,-355.7"/>
|
|
117
|
+
<polygon fill="black" stroke="black" points="247.88,-352.6 240.25,-359.95 250.8,-358.96 247.88,-352.6"/>
|
|
118
|
+
</g>
|
|
119
|
+
<!-- 7->5 -->
|
|
120
|
+
<g id="edge13" class="edge">
|
|
121
|
+
<title>7->5</title>
|
|
122
|
+
<path fill="none" stroke="black" d="M371.05,-215.88C375.69,-184.29 380.99,-116.06 350,-72 340.45,-58.42 326.41,-48.16 311.6,-40.47"/>
|
|
123
|
+
<polygon fill="black" stroke="black" points="312.84,-37.19 302.31,-36.01 309.81,-43.5 312.84,-37.19"/>
|
|
124
|
+
</g>
|
|
125
|
+
<!-- 7->6 -->
|
|
126
|
+
<g id="edge12" class="edge">
|
|
127
|
+
<title>7->6</title>
|
|
128
|
+
<path fill="none" stroke="black" d="M336.44,-215.88C319.34,-206.6 298.02,-195.03 279.68,-185.08"/>
|
|
129
|
+
<polygon fill="black" stroke="black" points="281.14,-181.88 270.68,-180.19 277.8,-188.04 281.14,-181.88"/>
|
|
130
|
+
</g>
|
|
131
|
+
<!-- 8->0 -->
|
|
132
|
+
<g id="edge15" class="edge">
|
|
133
|
+
<title>8->0</title>
|
|
134
|
+
<path fill="none" stroke="black" d="M241.99,-324.1C235.51,-332.55 226.69,-342.9 218.1,-352.2"/>
|
|
135
|
+
<polygon fill="black" stroke="black" points="215.33,-350.03 210.99,-359.7 220.41,-354.85 215.33,-350.03"/>
|
|
136
|
+
</g>
|
|
137
|
+
<!-- 8->5 -->
|
|
138
|
+
<g id="edge17" class="edge">
|
|
139
|
+
<title>8->5</title>
|
|
140
|
+
<path fill="none" stroke="black" d="M266.47,-287.62C290.36,-258.6 332,-198.15 317,-144 306.53,-106.2 281.25,-68.36 262.93,-44.38"/>
|
|
141
|
+
<polygon fill="black" stroke="black" points="265.45,-41.92 256.54,-36.2 259.94,-46.23 265.45,-41.92"/>
|
|
142
|
+
</g>
|
|
143
|
+
<!-- 8->6 -->
|
|
144
|
+
<g id="edge16" class="edge">
|
|
145
|
+
<title>8->6</title>
|
|
146
|
+
<path fill="none" stroke="black" d="M249.55,-287.87C247.51,-263.67 243.75,-219.21 241.31,-190.39"/>
|
|
147
|
+
<polygon fill="black" stroke="black" points="244.78,-189.86 240.45,-180.19 237.81,-190.45 244.78,-189.86"/>
|
|
148
|
+
</g>
|
|
149
|
+
<!-- 8->7 -->
|
|
150
|
+
<g id="edge14" class="edge">
|
|
151
|
+
<title>8->7</title>
|
|
152
|
+
<path fill="none" stroke="black" d="M279.62,-287.88C294.92,-278.72 313.94,-267.34 330.42,-257.48"/>
|
|
153
|
+
<polygon fill="black" stroke="black" points="332.48,-260.33 339.27,-252.19 328.89,-254.32 332.48,-260.33"/>
|
|
154
|
+
</g>
|
|
155
|
+
</g>
|
|
156
|
+
</svg>
|
|
@@ -126,19 +126,19 @@ use syn::{
|
|
|
126
126
|
/// either case the function is expected to return a `TransitionResult` to the appropriate state.
|
|
127
127
|
///
|
|
128
128
|
/// The first transition can be interpreted as "If the machine is in the locked state, when a
|
|
129
|
-
/// `CardReadable` event is seen, call `on_card_readable` (
|
|
129
|
+
/// `CardReadable` event is seen, call `on_card_readable` (passing in `CardData`) and transition to
|
|
130
130
|
/// the `ReadingCard` state.
|
|
131
131
|
///
|
|
132
132
|
/// The macro will generate a few things:
|
|
133
133
|
/// * A struct for the overall state machine, named with the provided name. Here:
|
|
134
|
-
/// ```
|
|
134
|
+
/// ```text
|
|
135
135
|
/// struct CardMachine {
|
|
136
136
|
/// state: CardMachineState,
|
|
137
137
|
/// shared_state: CardId,
|
|
138
138
|
/// }
|
|
139
139
|
/// ```
|
|
140
140
|
/// * An enum with a variant for each state, named with the provided name + "State".
|
|
141
|
-
/// ```
|
|
141
|
+
/// ```text
|
|
142
142
|
/// enum CardMachineState {
|
|
143
143
|
/// Locked(Locked),
|
|
144
144
|
/// ReadingCard(ReadingCard),
|
|
@@ -153,7 +153,7 @@ use syn::{
|
|
|
153
153
|
/// generated. This enum must be used as the destination "state" from those handlers.
|
|
154
154
|
/// * An enum with a variant for each event. You are expected to define the type (if any) contained
|
|
155
155
|
/// in the event variant.
|
|
156
|
-
/// ```
|
|
156
|
+
/// ```text
|
|
157
157
|
/// enum CardMachineEvents {
|
|
158
158
|
/// CardReadable(CardData)
|
|
159
159
|
/// }
|
|
@@ -565,7 +565,7 @@ impl StateMachineDefinition {
|
|
|
565
565
|
&self.shared_state
|
|
566
566
|
}
|
|
567
567
|
|
|
568
|
-
fn
|
|
568
|
+
fn has_reached_final_state(&self) -> bool {
|
|
569
569
|
self.state.is_final()
|
|
570
570
|
}
|
|
571
571
|
|
package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr
CHANGED
|
@@ -5,10 +5,8 @@ error[E0277]: the trait bound `One: From<Two>` is not satisfied
|
|
|
5
5
|
| ^^^ the trait `From<Two>` is not implemented for `One`
|
|
6
6
|
|
|
|
7
7
|
= note: required because of the requirements on the impl of `Into<One>` for `Two`
|
|
8
|
-
note: required by `TransitionResult::<Sm, Ds>::from`
|
|
8
|
+
note: required by a bound in `TransitionResult::<Sm, Ds>::from`
|
|
9
9
|
--> $WORKSPACE/fsm/rustfsm_trait/src/lib.rs
|
|
10
10
|
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
| | CurrentState: Into<Ds>,
|
|
14
|
-
| |_______________________________^
|
|
11
|
+
| CurrentState: Into<Ds>,
|
|
12
|
+
| ^^^^^^^^ required by this bound in `TransitionResult::<Sm, Ds>::from`
|