@temporalio/core-bridge 1.5.2 → 1.6.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 +255 -48
- package/package.json +4 -4
- 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/.buildkite/pipeline.yml +1 -3
- package/sdk-core/.cargo/config.toml +5 -2
- package/sdk-core/.github/workflows/heavy.yml +28 -0
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/README.md +9 -5
- package/sdk-core/client/src/lib.rs +211 -36
- package/sdk-core/client/src/raw.rs +1 -1
- package/sdk-core/client/src/retry.rs +32 -20
- package/sdk-core/core/Cargo.toml +23 -9
- package/sdk-core/core/src/abstractions.rs +11 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/core/src/core_tests/local_activities.rs +263 -22
- package/sdk-core/core/src/core_tests/queries.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +249 -5
- package/sdk-core/core/src/ephemeral_server/mod.rs +5 -6
- package/sdk-core/core/src/lib.rs +2 -0
- package/sdk-core/core/src/protosext/mod.rs +1 -1
- package/sdk-core/core/src/telemetry/log_export.rs +1 -1
- package/sdk-core/core/src/telemetry/mod.rs +23 -8
- package/sdk-core/core/src/test_help/mod.rs +8 -1
- package/sdk-core/core/src/worker/activities/local_activities.rs +259 -125
- package/sdk-core/core/src/worker/activities.rs +3 -2
- package/sdk-core/core/src/worker/mod.rs +53 -26
- package/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
- package/sdk-core/core/src/worker/workflow/history_update.rs +835 -277
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -17
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +73 -51
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -3
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +89 -58
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +4 -7
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +21 -9
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1021 -360
- package/sdk-core/core/src/worker/workflow/mod.rs +306 -346
- package/sdk-core/core/src/worker/workflow/run_cache.rs +29 -53
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +115 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +444 -714
- package/sdk-core/core-api/Cargo.toml +2 -0
- package/sdk-core/core-api/src/errors.rs +1 -34
- package/sdk-core/core-api/src/lib.rs +6 -2
- package/sdk-core/core-api/src/worker.rs +14 -1
- package/sdk-core/etc/deps.svg +115 -140
- package/sdk-core/etc/regen-depgraph.sh +5 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -6
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -3
- package/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
- package/sdk-core/protos/api_upstream/Makefile +5 -5
- package/sdk-core/protos/api_upstream/build/go.mod +7 -0
- package/sdk-core/protos/api_upstream/build/go.sum +5 -0
- package/sdk-core/protos/api_upstream/build/tools.go +29 -0
- package/sdk-core/protos/api_upstream/go.mod +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +9 -2
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +12 -19
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +3 -3
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -2
- package/sdk-core/protos/api_upstream/temporal/api/{update/v1/message.proto → enums/v1/interaction_type.proto} +11 -18
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -19
- package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +13 -8
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
- package/sdk-core/sdk/Cargo.toml +4 -3
- package/sdk-core/sdk/src/lib.rs +87 -21
- package/sdk-core/sdk/src/workflow_future.rs +7 -12
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -2
- package/sdk-core/sdk-core-protos/build.rs +36 -2
- package/sdk-core/sdk-core-protos/src/history_builder.rs +26 -19
- package/sdk-core/sdk-core-protos/src/history_info.rs +4 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +78 -34
- package/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
- package/sdk-core/test-utils/Cargo.toml +3 -1
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +50 -18
- package/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
- package/sdk-core/test-utils/src/workflows.rs +29 -0
- package/sdk-core/tests/fuzzy_workflow.rs +130 -0
- package/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +114 -7
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
- package/sdk-core/tests/integ_tests/metrics_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/polling_tests.rs +1 -39
- package/sdk-core/tests/integ_tests/queries_tests.rs +2 -127
- package/sdk-core/tests/integ_tests/visibility_tests.rs +52 -5
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +74 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +5 -13
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +2 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +69 -197
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +4 -28
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -19
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -19
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests.rs +5 -6
- package/sdk-core/tests/main.rs +2 -12
- package/sdk-core/tests/runner.rs +71 -34
- package/sdk-core/tests/wf_input_replay.rs +32 -0
- package/sdk-core/bridge-ffi/Cargo.toml +0 -24
- package/sdk-core/bridge-ffi/LICENSE.txt +0 -23
- package/sdk-core/bridge-ffi/build.rs +0 -25
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -224
- package/sdk-core/bridge-ffi/src/lib.rs +0 -746
- package/sdk-core/bridge-ffi/src/wrappers.rs +0 -221
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
- package/sdk-core/sdk/src/conversions.rs +0 -8
|
@@ -28,8 +28,8 @@ option go_package = "go.temporal.io/api/version/v1;version";
|
|
|
28
28
|
option java_package = "io.temporal.api.version.v1";
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "MessageProto";
|
|
31
|
-
option ruby_package = "
|
|
32
|
-
option csharp_namespace = "
|
|
31
|
+
option ruby_package = "Temporalio::Api::Version::V1";
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.Version.V1";
|
|
33
33
|
|
|
34
34
|
import "google/protobuf/timestamp.proto";
|
|
35
35
|
import "dependencies/gogoproto/gogo.proto";
|
|
@@ -28,8 +28,8 @@ option go_package = "go.temporal.io/api/workflow/v1;workflow";
|
|
|
28
28
|
option java_package = "io.temporal.api.workflow.v1";
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "MessageProto";
|
|
31
|
-
option ruby_package = "
|
|
32
|
-
option csharp_namespace = "
|
|
31
|
+
option ruby_package = "Temporalio::Api::Workflow::V1";
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.Workflow.V1";
|
|
33
33
|
|
|
34
34
|
import "google/protobuf/duration.proto";
|
|
35
35
|
import "google/protobuf/timestamp.proto";
|
|
@@ -28,8 +28,8 @@ option go_package = "go.temporal.io/api/workflowservice/v1;workflowservice";
|
|
|
28
28
|
option java_package = "io.temporal.api.workflowservice.v1";
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "RequestResponseProto";
|
|
31
|
-
option ruby_package = "
|
|
32
|
-
option csharp_namespace = "
|
|
31
|
+
option ruby_package = "Temporalio::Api::WorkflowService::V1";
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.WorkflowService.V1";
|
|
33
33
|
|
|
34
34
|
import "temporal/api/enums/v1/batch_operation.proto";
|
|
35
35
|
import "temporal/api/enums/v1/workflow.proto";
|
|
@@ -42,6 +42,7 @@ import "temporal/api/enums/v1/task_queue.proto";
|
|
|
42
42
|
import "temporal/api/enums/v1/update.proto";
|
|
43
43
|
import "temporal/api/common/v1/message.proto";
|
|
44
44
|
import "temporal/api/history/v1/message.proto";
|
|
45
|
+
import "temporal/api/interaction/v1/message.proto";
|
|
45
46
|
import "temporal/api/workflow/v1/message.proto";
|
|
46
47
|
import "temporal/api/command/v1/message.proto";
|
|
47
48
|
import "temporal/api/failure/v1/message.proto";
|
|
@@ -51,7 +52,6 @@ import "temporal/api/query/v1/message.proto";
|
|
|
51
52
|
import "temporal/api/replication/v1/message.proto";
|
|
52
53
|
import "temporal/api/schedule/v1/message.proto";
|
|
53
54
|
import "temporal/api/taskqueue/v1/message.proto";
|
|
54
|
-
import "temporal/api/update/v1/message.proto";
|
|
55
55
|
import "temporal/api/version/v1/message.proto";
|
|
56
56
|
import "temporal/api/batch/v1/message.proto";
|
|
57
57
|
|
|
@@ -267,6 +267,8 @@ message PollWorkflowTaskQueueResponse {
|
|
|
267
267
|
// Queries that should be executed after applying the history in this task. Responses should be
|
|
268
268
|
// attached to `RespondWorkflowTaskCompletedRequest::query_results`
|
|
269
269
|
map<string, temporal.api.query.v1.WorkflowQuery> queries = 14;
|
|
270
|
+
|
|
271
|
+
repeated temporal.api.interaction.v1.Invocation interactions = 15;
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
message RespondWorkflowTaskCompletedRequest {
|
|
@@ -304,6 +306,8 @@ message RespondWorkflowTaskCompletedResponse {
|
|
|
304
306
|
PollWorkflowTaskQueueResponse workflow_task = 1;
|
|
305
307
|
// See `ScheduleActivityTaskCommandAttributes::request_start`
|
|
306
308
|
repeated PollActivityTaskQueueResponse activity_tasks = 2;
|
|
309
|
+
|
|
310
|
+
int64 reset_history_event_id = 3;
|
|
307
311
|
}
|
|
308
312
|
|
|
309
313
|
message RespondWorkflowTaskFailedRequest {
|
|
@@ -1067,9 +1071,12 @@ message UpdateWorkflowRequest {
|
|
|
1067
1071
|
// part of the same execution chain as this id.
|
|
1068
1072
|
string first_execution_run_id = 5;
|
|
1069
1073
|
|
|
1074
|
+
// A string identifying the agent that requested this interaction.
|
|
1075
|
+
string identity = 6;
|
|
1076
|
+
|
|
1070
1077
|
// The name under which the workflow update function is registered and the
|
|
1071
1078
|
// arguments to pass to said function.
|
|
1072
|
-
temporal.api.
|
|
1079
|
+
temporal.api.interaction.v1.Input input = 7;
|
|
1073
1080
|
}
|
|
1074
1081
|
|
|
1075
1082
|
message UpdateWorkflowResponse {
|
|
@@ -1077,10 +1084,7 @@ message UpdateWorkflowResponse {
|
|
|
1077
1084
|
// polling if it is not returned as part of the gRPC response
|
|
1078
1085
|
bytes update_token = 1;
|
|
1079
1086
|
// The success or failure status of the update
|
|
1080
|
-
|
|
1081
|
-
temporal.api.common.v1.Payloads success = 2;
|
|
1082
|
-
temporal.api.failure.v1.Failure failure = 3;
|
|
1083
|
-
}
|
|
1087
|
+
temporal.api.interaction.v1.Output output = 2;
|
|
1084
1088
|
}
|
|
1085
1089
|
|
|
1086
1090
|
message StartBatchOperationRequest {
|
|
@@ -1097,6 +1101,7 @@ message StartBatchOperationRequest {
|
|
|
1097
1101
|
temporal.api.batch.v1.BatchOperationTermination termination_operation = 10;
|
|
1098
1102
|
temporal.api.batch.v1.BatchOperationSignal signal_operation = 11;
|
|
1099
1103
|
temporal.api.batch.v1.BatchOperationCancellation cancellation_operation = 12;
|
|
1104
|
+
temporal.api.batch.v1.BatchOperationDeletion deletion_operation = 13;
|
|
1100
1105
|
}
|
|
1101
1106
|
}
|
|
1102
1107
|
|
|
@@ -28,8 +28,8 @@ option go_package = "go.temporal.io/api/workflowservice/v1;workflowservice";
|
|
|
28
28
|
option java_package = "io.temporal.api.workflowservice.v1";
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "ServiceProto";
|
|
31
|
-
option ruby_package = "
|
|
32
|
-
option csharp_namespace = "
|
|
31
|
+
option ruby_package = "Temporalio::Api::WorkflowService::V1";
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.WorkflowService.V1";
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
import "temporal/api/workflowservice/v1/request_response.proto";
|
package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto
CHANGED
|
@@ -258,6 +258,8 @@ message RemoveFromCache {
|
|
|
258
258
|
// There was some fatal error processing the workflow, typically an internal error, but
|
|
259
259
|
// can also happen if then network drops out while paginating. Check message string.
|
|
260
260
|
FATAL = 8;
|
|
261
|
+
// Something went wrong attempting to fetch more history events.
|
|
262
|
+
PAGINATION_OR_HISTORY_FETCH = 9;
|
|
261
263
|
}
|
|
262
264
|
EvictionReason reason = 2;
|
|
263
265
|
}
|
|
@@ -28,8 +28,8 @@ option go_package = "go.temporal.io/api/testservice/v1;testservice";
|
|
|
28
28
|
option java_package = "io.temporal.api.testservice.v1";
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "RequestResponseProto";
|
|
31
|
-
option ruby_package = "
|
|
32
|
-
option csharp_namespace = "
|
|
31
|
+
option ruby_package = "Temporalio::Api::TestService::V1";
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.TestService.V1";
|
|
33
33
|
|
|
34
34
|
import "google/protobuf/duration.proto";
|
|
35
35
|
import "google/protobuf/timestamp.proto";
|
|
@@ -28,8 +28,8 @@ option go_package = "go.temporal.io/api/testservice/v1;testservice";
|
|
|
28
28
|
option java_package = "io.temporal.api.testservice.v1";
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "ServiceProto";
|
|
31
|
-
option ruby_package = "
|
|
32
|
-
option csharp_namespace = "
|
|
31
|
+
option ruby_package = "Temporalio::Api::TestService::V1";
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.TestService.V1";
|
|
33
33
|
|
|
34
34
|
import "temporal/api/testservice/v1/request_response.proto";
|
|
35
35
|
import "google/protobuf/empty.proto";
|
package/sdk-core/sdk/Cargo.toml
CHANGED
|
@@ -14,21 +14,22 @@ categories = ["development-tools"]
|
|
|
14
14
|
|
|
15
15
|
[dependencies]
|
|
16
16
|
async-trait = "0.1"
|
|
17
|
+
thiserror = "1.0"
|
|
17
18
|
anyhow = "1.0"
|
|
18
|
-
base64 = "0.
|
|
19
|
+
base64 = "0.21"
|
|
19
20
|
crossbeam = "0.8"
|
|
20
21
|
derive_more = "0.99"
|
|
21
22
|
futures = "0.3"
|
|
22
23
|
once_cell = "1.10"
|
|
23
24
|
parking_lot = { version = "0.12", features = ["send_guard"] }
|
|
24
|
-
prost-types = "0.
|
|
25
|
+
prost-types = { version = "0.4", package = "prost-wkt-types" }
|
|
25
26
|
sha2 = "0.10"
|
|
26
27
|
serde = "1.0"
|
|
27
28
|
tokio = { version = "1.1", features = ["rt", "rt-multi-thread", "parking_lot", "time", "fs"] }
|
|
28
29
|
tokio-util = { version = "0.7" }
|
|
29
30
|
tokio-stream = "0.1"
|
|
30
31
|
tonic = "0.8"
|
|
31
|
-
tracing =
|
|
32
|
+
tracing = "0.1"
|
|
32
33
|
|
|
33
34
|
[dependencies.temporal-sdk-core]
|
|
34
35
|
path = "../core"
|
package/sdk-core/sdk/src/lib.rs
CHANGED
|
@@ -46,7 +46,6 @@ extern crate tracing;
|
|
|
46
46
|
|
|
47
47
|
mod activity_context;
|
|
48
48
|
mod app_data;
|
|
49
|
-
mod conversions;
|
|
50
49
|
pub mod interceptors;
|
|
51
50
|
mod payload_converter;
|
|
52
51
|
mod workflow_context;
|
|
@@ -67,10 +66,12 @@ use anyhow::{anyhow, bail, Context};
|
|
|
67
66
|
use app_data::AppData;
|
|
68
67
|
use futures::{future::BoxFuture, FutureExt, StreamExt, TryFutureExt, TryStreamExt};
|
|
69
68
|
use std::{
|
|
69
|
+
any::{Any, TypeId},
|
|
70
70
|
cell::RefCell,
|
|
71
71
|
collections::HashMap,
|
|
72
72
|
fmt::{Debug, Display, Formatter},
|
|
73
73
|
future::Future,
|
|
74
|
+
panic::AssertUnwindSafe,
|
|
74
75
|
sync::Arc,
|
|
75
76
|
};
|
|
76
77
|
use temporal_client::ClientOptionsBuilder;
|
|
@@ -307,22 +308,17 @@ impl Worker {
|
|
|
307
308
|
// makes tests which use mocks dramatically more manageable.
|
|
308
309
|
async {
|
|
309
310
|
if !act_half.activity_fns.is_empty() {
|
|
310
|
-
let shutdown_token = shutdown_token.clone();
|
|
311
311
|
loop {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
act_half.activity_task_handler(
|
|
318
|
-
common.worker.clone(),
|
|
319
|
-
safe_app_data.clone(),
|
|
320
|
-
common.task_queue.clone(),
|
|
321
|
-
activity?
|
|
322
|
-
)?;
|
|
323
|
-
},
|
|
324
|
-
_ = shutdown_token.cancelled() => { break }
|
|
312
|
+
let activity = common.worker.poll_activity_task().await;
|
|
313
|
+
if matches!(activity, Err(PollActivityError::ShutDown)) {
|
|
314
|
+
break;
|
|
325
315
|
}
|
|
316
|
+
act_half.activity_task_handler(
|
|
317
|
+
common.worker.clone(),
|
|
318
|
+
safe_app_data.clone(),
|
|
319
|
+
common.task_queue.clone(),
|
|
320
|
+
activity?,
|
|
321
|
+
)?;
|
|
326
322
|
}
|
|
327
323
|
};
|
|
328
324
|
Result::<_, anyhow::Error>::Ok(())
|
|
@@ -336,6 +332,7 @@ impl Worker {
|
|
|
336
332
|
i.on_shutdown(self);
|
|
337
333
|
}
|
|
338
334
|
self.common.worker.shutdown().await;
|
|
335
|
+
debug!("Worker shutdown complete");
|
|
339
336
|
self.app_data = Some(
|
|
340
337
|
Arc::try_unwrap(safe_app_data)
|
|
341
338
|
.map_err(|_| anyhow!("some references of AppData exist on worker shutdown"))?,
|
|
@@ -413,7 +410,7 @@ impl WorkflowHalf {
|
|
|
413
410
|
);
|
|
414
411
|
let jh = tokio::spawn(async move {
|
|
415
412
|
tokio::select! {
|
|
416
|
-
r = wff => r,
|
|
413
|
+
r = wff.fuse() => r,
|
|
417
414
|
// TODO: This probably shouldn't abort early, as it could cause an in-progress
|
|
418
415
|
// complete to abort. Send synthetic remove activation
|
|
419
416
|
_ = shutdown_token.cancelled() => {
|
|
@@ -486,15 +483,30 @@ impl ActivityHalf {
|
|
|
486
483
|
start,
|
|
487
484
|
);
|
|
488
485
|
tokio::spawn(async move {
|
|
489
|
-
let output = (act_fn.act_func)(ctx, arg)
|
|
486
|
+
let output = AssertUnwindSafe((act_fn.act_func)(ctx, arg))
|
|
487
|
+
.catch_unwind()
|
|
488
|
+
.await;
|
|
490
489
|
let result = match output {
|
|
491
|
-
|
|
492
|
-
|
|
490
|
+
Err(e) => ActivityExecutionResult::fail(Failure::application_failure(
|
|
491
|
+
format!("Activity function panicked: {}", panic_formatter(e)),
|
|
492
|
+
true,
|
|
493
|
+
)),
|
|
494
|
+
Ok(Ok(ActExitValue::Normal(p))) => ActivityExecutionResult::ok(p),
|
|
495
|
+
Ok(Ok(ActExitValue::WillCompleteAsync)) => {
|
|
493
496
|
ActivityExecutionResult::will_complete_async()
|
|
494
497
|
}
|
|
495
|
-
Err(err) => match err.downcast::<ActivityCancelledError>() {
|
|
498
|
+
Ok(Err(err)) => match err.downcast::<ActivityCancelledError>() {
|
|
496
499
|
Ok(ce) => ActivityExecutionResult::cancel_from_details(ce.details),
|
|
497
|
-
Err(other_err) =>
|
|
500
|
+
Err(other_err) => {
|
|
501
|
+
match other_err.downcast::<NonRetryableActivityError>() {
|
|
502
|
+
Ok(nre) => ActivityExecutionResult::fail(
|
|
503
|
+
Failure::application_failure_from_error(nre.into(), true),
|
|
504
|
+
),
|
|
505
|
+
Err(other_err) => ActivityExecutionResult::fail(
|
|
506
|
+
Failure::application_failure_from_error(other_err, false),
|
|
507
|
+
),
|
|
508
|
+
}
|
|
509
|
+
}
|
|
498
510
|
},
|
|
499
511
|
};
|
|
500
512
|
worker
|
|
@@ -749,6 +761,14 @@ pub struct ActivityFunction {
|
|
|
749
761
|
pub struct ActivityCancelledError {
|
|
750
762
|
details: Option<Payload>,
|
|
751
763
|
}
|
|
764
|
+
impl ActivityCancelledError {
|
|
765
|
+
/// Include some details as part of concluding the activity as cancelled
|
|
766
|
+
pub fn with_details(payload: Payload) -> Self {
|
|
767
|
+
Self {
|
|
768
|
+
details: Some(payload),
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
752
772
|
impl std::error::Error for ActivityCancelledError {}
|
|
753
773
|
impl Display for ActivityCancelledError {
|
|
754
774
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
@@ -756,6 +776,16 @@ impl Display for ActivityCancelledError {
|
|
|
756
776
|
}
|
|
757
777
|
}
|
|
758
778
|
|
|
779
|
+
/// Return this error to indicate that your activity non-retryable
|
|
780
|
+
/// this is a transparent wrapper around anyhow Error so essentially any type of error
|
|
781
|
+
/// could be used here.
|
|
782
|
+
///
|
|
783
|
+
/// In your activity function. Return something along the lines of:
|
|
784
|
+
/// `Err(NonRetryableActivityError(anyhow::anyhow!("This should *not* be retried")).into())`
|
|
785
|
+
#[derive(Debug, thiserror::Error)]
|
|
786
|
+
#[error(transparent)]
|
|
787
|
+
pub struct NonRetryableActivityError(pub anyhow::Error);
|
|
788
|
+
|
|
759
789
|
/// Closures / functions which can be turned into activity functions implement this trait
|
|
760
790
|
pub trait IntoActivityFunc<Args, Res, Out> {
|
|
761
791
|
/// Consume the closure or fn pointer and turned it into a boxed activity function
|
|
@@ -793,3 +823,39 @@ where
|
|
|
793
823
|
Arc::new(wrapper)
|
|
794
824
|
}
|
|
795
825
|
}
|
|
826
|
+
|
|
827
|
+
/// Attempts to turn caught panics into something printable
|
|
828
|
+
fn panic_formatter(panic: Box<dyn Any>) -> Box<dyn Display> {
|
|
829
|
+
_panic_formatter::<&str>(panic)
|
|
830
|
+
}
|
|
831
|
+
fn _panic_formatter<T: 'static + PrintablePanicType>(panic: Box<dyn Any>) -> Box<dyn Display> {
|
|
832
|
+
match panic.downcast::<T>() {
|
|
833
|
+
Ok(d) => d,
|
|
834
|
+
Err(orig) => {
|
|
835
|
+
if TypeId::of::<<T as PrintablePanicType>::NextType>()
|
|
836
|
+
== TypeId::of::<EndPrintingAttempts>()
|
|
837
|
+
{
|
|
838
|
+
return Box::new("Couldn't turn panic into a string");
|
|
839
|
+
}
|
|
840
|
+
_panic_formatter::<T::NextType>(orig)
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
trait PrintablePanicType: Display {
|
|
845
|
+
type NextType: PrintablePanicType;
|
|
846
|
+
}
|
|
847
|
+
impl PrintablePanicType for &str {
|
|
848
|
+
type NextType = String;
|
|
849
|
+
}
|
|
850
|
+
impl PrintablePanicType for String {
|
|
851
|
+
type NextType = EndPrintingAttempts;
|
|
852
|
+
}
|
|
853
|
+
struct EndPrintingAttempts {}
|
|
854
|
+
impl Display for EndPrintingAttempts {
|
|
855
|
+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
856
|
+
write!(f, "Will never be printed")
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
impl PrintablePanicType for EndPrintingAttempts {
|
|
860
|
+
type NextType = EndPrintingAttempts;
|
|
861
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
WorkflowResult,
|
|
2
|
+
panic_formatter, workflow_context::WfContextSharedData, CancellableID, RustWfCmd, SignalData,
|
|
3
|
+
TimerResult, UnblockEvent, WfContext, WfExitValue, WorkflowFunction, WorkflowResult,
|
|
5
4
|
};
|
|
6
5
|
use anyhow::{anyhow, bail, Context as AnyhowContext, Error};
|
|
7
6
|
use crossbeam::channel::Receiver;
|
|
@@ -132,10 +131,7 @@ impl WorkflowFuture {
|
|
|
132
131
|
fn fail_wft(&self, run_id: String, fail: Error) {
|
|
133
132
|
warn!("Workflow task failed for {}: {}", run_id, fail);
|
|
134
133
|
self.outgoing_completions
|
|
135
|
-
.send(WorkflowActivationCompletion::fail(
|
|
136
|
-
run_id,
|
|
137
|
-
anyhow_to_fail(fail),
|
|
138
|
-
))
|
|
134
|
+
.send(WorkflowActivationCompletion::fail(run_id, fail.into()))
|
|
139
135
|
.expect("Completion channel intact");
|
|
140
136
|
}
|
|
141
137
|
|
|
@@ -218,6 +214,9 @@ impl WorkflowFuture {
|
|
|
218
214
|
}
|
|
219
215
|
|
|
220
216
|
Variant::RemoveFromCache(_) => {
|
|
217
|
+
// TODO: Need to abort any spawned tasks, etc. See also cancel WF.
|
|
218
|
+
// How best to do this in executor agnostic way? Is that possible?
|
|
219
|
+
// -- tokio JoinSet does this in a nice way.
|
|
221
220
|
return Ok(true);
|
|
222
221
|
}
|
|
223
222
|
}
|
|
@@ -283,11 +282,7 @@ impl Future for WorkflowFuture {
|
|
|
283
282
|
.poll_unpin(cx)
|
|
284
283
|
{
|
|
285
284
|
Poll::Ready(Err(e)) => {
|
|
286
|
-
let errmsg = format!(
|
|
287
|
-
"Workflow function panicked: {:?}",
|
|
288
|
-
// Panics are typically strings
|
|
289
|
-
e.downcast::<String>()
|
|
290
|
-
);
|
|
285
|
+
let errmsg = format!("Workflow function panicked: {}", panic_formatter(e));
|
|
291
286
|
warn!("{}", errmsg);
|
|
292
287
|
self.outgoing_completions
|
|
293
288
|
.send(WorkflowActivationCompletion::fail(
|
|
@@ -12,13 +12,15 @@ categories = ["development-tools"]
|
|
|
12
12
|
|
|
13
13
|
[features]
|
|
14
14
|
history_builders = ["uuid", "rand"]
|
|
15
|
+
serde_serialize = []
|
|
15
16
|
|
|
16
17
|
[dependencies]
|
|
17
18
|
anyhow = "1.0"
|
|
18
|
-
base64 = "0.
|
|
19
|
+
base64 = "0.21"
|
|
19
20
|
derive_more = "0.99"
|
|
20
21
|
prost = "0.11"
|
|
21
|
-
prost-
|
|
22
|
+
prost-wkt = "0.4"
|
|
23
|
+
prost-wkt-types = "0.4"
|
|
22
24
|
rand = { version = "0.8", optional = true }
|
|
23
25
|
serde = { version = "1.0", features = ["derive"] }
|
|
24
26
|
serde_json = "1.0"
|
|
@@ -28,3 +30,4 @@ uuid = { version = "1.1", features = ["v4"], optional = true }
|
|
|
28
30
|
|
|
29
31
|
[build-dependencies]
|
|
30
32
|
tonic-build = "0.8"
|
|
33
|
+
prost-wkt-build = "0.4"
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
use std::{env, path::PathBuf};
|
|
2
|
+
|
|
1
3
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
2
4
|
println!("cargo:rerun-if-changed=../protos");
|
|
5
|
+
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
6
|
+
let descriptor_file = out.join("descriptors.bin");
|
|
3
7
|
tonic_build::configure()
|
|
4
8
|
// We don't actually want to build the grpc definitions - we don't need them (for now).
|
|
5
9
|
// Just build the message structs.
|
|
@@ -74,7 +78,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
74
78
|
// All external data is useful to be able to JSON serialize, so it can render in web UI
|
|
75
79
|
.type_attribute(
|
|
76
80
|
".coresdk.external_data",
|
|
77
|
-
"#[derive(::serde::Serialize, ::serde::Deserialize)]",
|
|
81
|
+
"#[cfg_attr(not(feature = \"serde_serialize\"), derive(::serde::Serialize, ::serde::Deserialize))]",
|
|
82
|
+
)
|
|
83
|
+
.type_attribute(
|
|
84
|
+
".",
|
|
85
|
+
"#[cfg_attr(feature = \"serde_serialize\", derive(::serde::Serialize, ::serde::Deserialize))]",
|
|
78
86
|
)
|
|
79
87
|
.field_attribute(
|
|
80
88
|
"coresdk.external_data.LocalActivityMarkerData.complete_time",
|
|
@@ -88,10 +96,26 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
88
96
|
"coresdk.external_data.LocalActivityMarkerData.backoff",
|
|
89
97
|
"#[serde(with = \"opt_duration\")]",
|
|
90
98
|
)
|
|
99
|
+
.extern_path(
|
|
100
|
+
".google.protobuf.Any",
|
|
101
|
+
"::prost_wkt_types::Any"
|
|
102
|
+
)
|
|
103
|
+
.extern_path(
|
|
104
|
+
".google.protobuf.Timestamp",
|
|
105
|
+
"::prost_wkt_types::Timestamp"
|
|
106
|
+
)
|
|
107
|
+
.extern_path(
|
|
108
|
+
".google.protobuf.Duration",
|
|
109
|
+
"::prost_wkt_types::Duration"
|
|
110
|
+
)
|
|
111
|
+
.extern_path(
|
|
112
|
+
".google.protobuf.Value",
|
|
113
|
+
"::prost_wkt_types::Value"
|
|
114
|
+
)
|
|
115
|
+
.file_descriptor_set_path(#[allow(clippy::needless_borrow)] &descriptor_file)
|
|
91
116
|
.compile(
|
|
92
117
|
&[
|
|
93
118
|
"../protos/local/temporal/sdk/core/core_interface.proto",
|
|
94
|
-
"../protos/local/temporal/sdk/core/bridge/bridge.proto",
|
|
95
119
|
"../protos/api_upstream/temporal/api/workflowservice/v1/service.proto",
|
|
96
120
|
"../protos/api_upstream/temporal/api/operatorservice/v1/service.proto",
|
|
97
121
|
"../protos/testsrv_upstream/temporal/api/testservice/v1/service.proto",
|
|
@@ -104,5 +128,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
104
128
|
"../protos/grpc",
|
|
105
129
|
],
|
|
106
130
|
)?;
|
|
131
|
+
|
|
132
|
+
#[cfg(feature = "serde_serialize")]
|
|
133
|
+
{
|
|
134
|
+
use prost_wkt_build::{FileDescriptorSet, Message};
|
|
135
|
+
|
|
136
|
+
let descriptor_bytes = std::fs::read(descriptor_file)?;
|
|
137
|
+
let descriptor = FileDescriptorSet::decode(&descriptor_bytes[..])?;
|
|
138
|
+
prost_wkt_build::add_serde(out, descriptor);
|
|
139
|
+
}
|
|
140
|
+
|
|
107
141
|
Ok(())
|
|
108
142
|
}
|
|
@@ -18,7 +18,7 @@ use crate::{
|
|
|
18
18
|
HistoryInfo,
|
|
19
19
|
};
|
|
20
20
|
use anyhow::bail;
|
|
21
|
-
use
|
|
21
|
+
use prost_wkt_types::Timestamp;
|
|
22
22
|
use std::time::{Duration, SystemTime};
|
|
23
23
|
use uuid::Uuid;
|
|
24
24
|
|
|
@@ -292,22 +292,21 @@ impl TestHistoryBuilder {
|
|
|
292
292
|
activity_id: &str,
|
|
293
293
|
payload: Option<Payload>,
|
|
294
294
|
failure: Option<Failure>,
|
|
295
|
-
|
|
295
|
+
detail_mutator: impl FnOnce(&mut LocalActivityMarkerData),
|
|
296
296
|
) {
|
|
297
|
+
let mut lamd = LocalActivityMarkerData {
|
|
298
|
+
seq,
|
|
299
|
+
attempt: 1,
|
|
300
|
+
activity_id: activity_id.to_string(),
|
|
301
|
+
activity_type: "some_act_type".to_string(),
|
|
302
|
+
complete_time: None,
|
|
303
|
+
backoff: None,
|
|
304
|
+
original_schedule_time: None,
|
|
305
|
+
};
|
|
306
|
+
detail_mutator(&mut lamd);
|
|
297
307
|
let attrs = MarkerRecordedEventAttributes {
|
|
298
308
|
marker_name: LOCAL_ACTIVITY_MARKER_NAME.to_string(),
|
|
299
|
-
details: build_local_activity_marker_details(
|
|
300
|
-
LocalActivityMarkerData {
|
|
301
|
-
seq,
|
|
302
|
-
attempt: 1,
|
|
303
|
-
activity_id: activity_id.to_string(),
|
|
304
|
-
activity_type: "some_act_type".to_string(),
|
|
305
|
-
complete_time,
|
|
306
|
-
backoff: None,
|
|
307
|
-
original_schedule_time: None,
|
|
308
|
-
},
|
|
309
|
-
payload,
|
|
310
|
-
),
|
|
309
|
+
details: build_local_activity_marker_details(lamd, payload),
|
|
311
310
|
workflow_task_completed_event_id: self.previous_task_completed_id,
|
|
312
311
|
failure,
|
|
313
312
|
..Default::default()
|
|
@@ -321,7 +320,7 @@ impl TestHistoryBuilder {
|
|
|
321
320
|
activity_id: &str,
|
|
322
321
|
payload: Payload,
|
|
323
322
|
) {
|
|
324
|
-
self.add_local_activity_marker(seq, activity_id, Some(payload), None,
|
|
323
|
+
self.add_local_activity_marker(seq, activity_id, Some(payload), None, |_| {});
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
pub fn add_local_activity_result_marker_with_time(
|
|
@@ -331,7 +330,9 @@ impl TestHistoryBuilder {
|
|
|
331
330
|
payload: Payload,
|
|
332
331
|
complete_time: Timestamp,
|
|
333
332
|
) {
|
|
334
|
-
self.add_local_activity_marker(seq, activity_id, Some(payload), None,
|
|
333
|
+
self.add_local_activity_marker(seq, activity_id, Some(payload), None, |d| {
|
|
334
|
+
d.complete_time = Some(complete_time)
|
|
335
|
+
});
|
|
335
336
|
}
|
|
336
337
|
|
|
337
338
|
pub fn add_local_activity_fail_marker(
|
|
@@ -340,7 +341,7 @@ impl TestHistoryBuilder {
|
|
|
340
341
|
activity_id: &str,
|
|
341
342
|
failure: Failure,
|
|
342
343
|
) {
|
|
343
|
-
self.add_local_activity_marker(seq, activity_id, None, Some(failure),
|
|
344
|
+
self.add_local_activity_marker(seq, activity_id, None, Some(failure), |_| {});
|
|
344
345
|
}
|
|
345
346
|
|
|
346
347
|
pub fn add_local_activity_cancel_marker(&mut self, seq: u32, activity_id: &str) {
|
|
@@ -358,7 +359,7 @@ impl TestHistoryBuilder {
|
|
|
358
359
|
)),
|
|
359
360
|
encoded_attributes: Default::default(),
|
|
360
361
|
}),
|
|
361
|
-
|
|
362
|
+
|_| {},
|
|
362
363
|
);
|
|
363
364
|
}
|
|
364
365
|
|
|
@@ -441,6 +442,12 @@ impl TestHistoryBuilder {
|
|
|
441
442
|
);
|
|
442
443
|
}
|
|
443
444
|
|
|
445
|
+
pub fn add_wfe_started_with_wft_timeout(&mut self, dur: Duration) {
|
|
446
|
+
let mut wesattrs = default_wes_attribs();
|
|
447
|
+
wesattrs.workflow_task_timeout = Some(dur.try_into().unwrap());
|
|
448
|
+
self.add(EventType::WorkflowExecutionStarted, wesattrs.into());
|
|
449
|
+
}
|
|
450
|
+
|
|
444
451
|
pub fn get_orig_run_id(&self) -> &str {
|
|
445
452
|
&self.original_run_id
|
|
446
453
|
}
|
|
@@ -465,7 +472,7 @@ impl TestHistoryBuilder {
|
|
|
465
472
|
}
|
|
466
473
|
|
|
467
474
|
/// Return most recent wft start time or panic if unset
|
|
468
|
-
pub fn wft_start_time(&self) ->
|
|
475
|
+
pub fn wft_start_time(&self) -> Timestamp {
|
|
469
476
|
self.events[(self.workflow_task_scheduled_event_id + 1) as usize]
|
|
470
477
|
.event_time
|
|
471
478
|
.clone()
|
|
@@ -136,6 +136,10 @@ impl HistoryInfo {
|
|
|
136
136
|
&self.events
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
pub fn into_events(self) -> Vec<HistoryEvent> {
|
|
140
|
+
self.events
|
|
141
|
+
}
|
|
142
|
+
|
|
139
143
|
/// Extract run id from the workflow execution started attributes.
|
|
140
144
|
pub fn orig_run_id(&self) -> &str {
|
|
141
145
|
&self.wf_exe_started_attrs.original_execution_run_id
|