@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.
Files changed (153) hide show
  1. package/Cargo.lock +255 -48
  2. package/package.json +4 -4
  3. package/releases/aarch64-apple-darwin/index.node +0 -0
  4. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  5. package/releases/x86_64-apple-darwin/index.node +0 -0
  6. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  7. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  8. package/sdk-core/.buildkite/pipeline.yml +1 -3
  9. package/sdk-core/.cargo/config.toml +5 -2
  10. package/sdk-core/.github/workflows/heavy.yml +28 -0
  11. package/sdk-core/Cargo.toml +1 -1
  12. package/sdk-core/README.md +9 -5
  13. package/sdk-core/client/src/lib.rs +211 -36
  14. package/sdk-core/client/src/raw.rs +1 -1
  15. package/sdk-core/client/src/retry.rs +32 -20
  16. package/sdk-core/core/Cargo.toml +23 -9
  17. package/sdk-core/core/src/abstractions.rs +11 -0
  18. package/sdk-core/core/src/core_tests/activity_tasks.rs +6 -5
  19. package/sdk-core/core/src/core_tests/local_activities.rs +263 -22
  20. package/sdk-core/core/src/core_tests/queries.rs +2 -2
  21. package/sdk-core/core/src/core_tests/workflow_tasks.rs +249 -5
  22. package/sdk-core/core/src/ephemeral_server/mod.rs +5 -6
  23. package/sdk-core/core/src/lib.rs +2 -0
  24. package/sdk-core/core/src/protosext/mod.rs +1 -1
  25. package/sdk-core/core/src/telemetry/log_export.rs +1 -1
  26. package/sdk-core/core/src/telemetry/mod.rs +23 -8
  27. package/sdk-core/core/src/test_help/mod.rs +8 -1
  28. package/sdk-core/core/src/worker/activities/local_activities.rs +259 -125
  29. package/sdk-core/core/src/worker/activities.rs +3 -2
  30. package/sdk-core/core/src/worker/mod.rs +53 -26
  31. package/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  32. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  33. package/sdk-core/core/src/worker/workflow/history_update.rs +835 -277
  34. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -17
  35. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +3 -5
  36. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -2
  37. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
  38. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -2
  39. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -2
  40. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -2
  41. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +73 -51
  42. package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -3
  43. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +4 -4
  44. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -2
  45. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +3 -5
  46. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +6 -7
  47. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  48. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +4 -4
  49. package/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
  50. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +89 -58
  51. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +4 -7
  52. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +21 -9
  53. package/sdk-core/core/src/worker/workflow/managed_run.rs +1021 -360
  54. package/sdk-core/core/src/worker/workflow/mod.rs +306 -346
  55. package/sdk-core/core/src/worker/workflow/run_cache.rs +29 -53
  56. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  57. package/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  58. package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +115 -0
  59. package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  60. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +444 -714
  61. package/sdk-core/core-api/Cargo.toml +2 -0
  62. package/sdk-core/core-api/src/errors.rs +1 -34
  63. package/sdk-core/core-api/src/lib.rs +6 -2
  64. package/sdk-core/core-api/src/worker.rs +14 -1
  65. package/sdk-core/etc/deps.svg +115 -140
  66. package/sdk-core/etc/regen-depgraph.sh +5 -0
  67. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -6
  68. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -3
  69. package/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  70. package/sdk-core/protos/api_upstream/Makefile +5 -5
  71. package/sdk-core/protos/api_upstream/build/go.mod +7 -0
  72. package/sdk-core/protos/api_upstream/build/go.sum +5 -0
  73. package/sdk-core/protos/api_upstream/build/tools.go +29 -0
  74. package/sdk-core/protos/api_upstream/go.mod +6 -0
  75. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +9 -2
  76. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +12 -19
  77. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
  78. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  79. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +3 -2
  80. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  81. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +3 -3
  82. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -2
  83. package/sdk-core/protos/api_upstream/temporal/api/{update/v1/message.proto → enums/v1/interaction_type.proto} +11 -18
  84. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  85. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  86. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  87. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  88. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  89. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
  90. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  91. package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  92. package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  93. package/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  94. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -19
  95. package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
  96. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
  97. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -2
  98. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
  99. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  100. package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  101. package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
  102. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
  103. package/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  104. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -2
  105. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +13 -8
  106. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  107. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  108. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  109. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  110. package/sdk-core/sdk/Cargo.toml +4 -3
  111. package/sdk-core/sdk/src/lib.rs +87 -21
  112. package/sdk-core/sdk/src/workflow_future.rs +7 -12
  113. package/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  114. package/sdk-core/sdk-core-protos/build.rs +36 -2
  115. package/sdk-core/sdk-core-protos/src/history_builder.rs +26 -19
  116. package/sdk-core/sdk-core-protos/src/history_info.rs +4 -0
  117. package/sdk-core/sdk-core-protos/src/lib.rs +78 -34
  118. package/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  119. package/sdk-core/test-utils/Cargo.toml +3 -1
  120. package/sdk-core/test-utils/src/histfetch.rs +1 -1
  121. package/sdk-core/test-utils/src/lib.rs +50 -18
  122. package/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  123. package/sdk-core/test-utils/src/workflows.rs +29 -0
  124. package/sdk-core/tests/fuzzy_workflow.rs +130 -0
  125. package/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +114 -7
  126. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
  127. package/sdk-core/tests/integ_tests/metrics_tests.rs +1 -1
  128. package/sdk-core/tests/integ_tests/polling_tests.rs +1 -39
  129. package/sdk-core/tests/integ_tests/queries_tests.rs +2 -127
  130. package/sdk-core/tests/integ_tests/visibility_tests.rs +52 -5
  131. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +74 -1
  132. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +5 -13
  133. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +1 -1
  134. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +2 -10
  135. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +69 -197
  136. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +4 -28
  137. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  138. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +14 -14
  139. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -19
  140. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -19
  141. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
  142. package/sdk-core/tests/integ_tests/workflow_tests.rs +5 -6
  143. package/sdk-core/tests/main.rs +2 -12
  144. package/sdk-core/tests/runner.rs +71 -34
  145. package/sdk-core/tests/wf_input_replay.rs +32 -0
  146. package/sdk-core/bridge-ffi/Cargo.toml +0 -24
  147. package/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  148. package/sdk-core/bridge-ffi/build.rs +0 -25
  149. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -224
  150. package/sdk-core/bridge-ffi/src/lib.rs +0 -746
  151. package/sdk-core/bridge-ffi/src/wrappers.rs +0 -221
  152. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  153. 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 = "Temporal::Api::Version::V1";
32
- option csharp_namespace = "Temporal.Api.Version.V1";
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 = "Temporal::Api::Workflow::V1";
32
- option csharp_namespace = "Temporal.Api.Workflow.V1";
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 = "Temporal::Api::WorkflowService::V1";
32
- option csharp_namespace = "Temporal.Api.WorkflowService.V1";
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.update.v1.WorkflowUpdate update = 6;
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
- oneof result {
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 = "Temporal::Api::WorkflowService::V1";
32
- option csharp_namespace = "Temporal.Api.WorkflowService.V1";
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";
@@ -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 = "Temporal::Api::TestService::V1";
32
- option csharp_namespace = "Temporal.Api.TestService.V1";
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 = "Temporal::Api::TestService::V1";
32
- option csharp_namespace = "Temporal.Api.TestService.V1";
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";
@@ -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.13"
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.11"
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 = { version = "0.1", features = ["log-always"] }
32
+ tracing = "0.1"
32
33
 
33
34
  [dependencies.temporal-sdk-core]
34
35
  path = "../core"
@@ -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
- tokio::select! {
313
- activity = common.worker.poll_activity_task() => {
314
- if matches!(activity, Err(PollActivityError::ShutDown)) {
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).await;
486
+ let output = AssertUnwindSafe((act_fn.act_func)(ctx, arg))
487
+ .catch_unwind()
488
+ .await;
490
489
  let result = match output {
491
- Ok(ActExitValue::Normal(p)) => ActivityExecutionResult::ok(p),
492
- Ok(ActExitValue::WillCompleteAsync) => {
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) => ActivityExecutionResult::fail(other_err.into()),
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
- conversions::anyhow_to_fail, workflow_context::WfContextSharedData, CancellableID, RustWfCmd,
3
- SignalData, TimerResult, UnblockEvent, WfContext, WfExitValue, WorkflowFunction,
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.13"
19
+ base64 = "0.21"
19
20
  derive_more = "0.99"
20
21
  prost = "0.11"
21
- prost-types = "0.11"
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 prost_types::Timestamp;
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
- complete_time: Option<Timestamp>,
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, 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, Some(complete_time));
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), None);
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
- None,
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) -> prost_types::Timestamp {
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