temporalio 0.0.2 → 0.1.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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -23
  3. data/bridge/Cargo.lock +168 -59
  4. data/bridge/Cargo.toml +4 -2
  5. data/bridge/sdk-core/README.md +19 -6
  6. data/bridge/sdk-core/client/src/lib.rs +215 -39
  7. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  8. data/bridge/sdk-core/client/src/raw.rs +4 -4
  9. data/bridge/sdk-core/client/src/retry.rs +32 -20
  10. data/bridge/sdk-core/core/Cargo.toml +22 -9
  11. data/bridge/sdk-core/core/src/abstractions.rs +203 -14
  12. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +76 -41
  13. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  14. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +204 -83
  15. data/bridge/sdk-core/core/src/core_tests/queries.rs +3 -4
  16. data/bridge/sdk-core/core/src/core_tests/workers.rs +1 -3
  17. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +397 -54
  18. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  19. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  20. data/bridge/sdk-core/core/src/lib.rs +16 -9
  21. data/bridge/sdk-core/core/src/telemetry/log_export.rs +1 -1
  22. data/bridge/sdk-core/core/src/telemetry/metrics.rs +69 -35
  23. data/bridge/sdk-core/core/src/telemetry/mod.rs +29 -13
  24. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +17 -12
  25. data/bridge/sdk-core/core/src/test_help/mod.rs +62 -12
  26. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  27. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +352 -122
  29. data/bridge/sdk-core/core/src/worker/activities.rs +233 -157
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +22 -2
  31. data/bridge/sdk-core/core/src/worker/client.rs +18 -2
  32. data/bridge/sdk-core/core/src/worker/mod.rs +165 -58
  33. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  34. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  35. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +856 -277
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +100 -43
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +7 -7
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +5 -4
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +87 -27
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +5 -4
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +5 -4
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +5 -4
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +137 -62
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +25 -17
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +7 -6
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +103 -152
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +7 -7
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -7
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +5 -16
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +201 -121
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +11 -14
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +30 -15
  55. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1026 -376
  56. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +460 -384
  57. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  58. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  59. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  60. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +448 -718
  63. data/bridge/sdk-core/core-api/Cargo.toml +2 -1
  64. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  65. data/bridge/sdk-core/core-api/src/lib.rs +6 -2
  66. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -6
  67. data/bridge/sdk-core/core-api/src/worker.rs +14 -1
  68. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  69. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  70. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  71. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  85. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  86. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  87. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  88. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  89. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  90. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  91. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +7 -0
  92. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +1 -0
  93. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  94. data/bridge/sdk-core/sdk/Cargo.toml +3 -2
  95. data/bridge/sdk-core/sdk/src/lib.rs +87 -20
  96. data/bridge/sdk-core/sdk/src/workflow_future.rs +9 -8
  97. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  98. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -1
  99. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +100 -87
  100. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +5 -1
  101. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +175 -57
  102. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  103. data/bridge/sdk-core/test-utils/Cargo.toml +3 -1
  104. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  105. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  106. data/bridge/sdk-core/test-utils/src/lib.rs +82 -23
  107. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  108. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  109. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  110. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  111. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  112. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
  113. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
  114. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
  115. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  116. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  117. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  118. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  119. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  120. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  121. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  122. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +72 -191
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  127. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  128. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  129. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  130. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  131. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  132. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +10 -11
  133. data/bridge/sdk-core/tests/main.rs +3 -13
  134. data/bridge/sdk-core/tests/runner.rs +75 -36
  135. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  136. data/bridge/src/connection.rs +41 -25
  137. data/bridge/src/lib.rs +269 -14
  138. data/bridge/src/runtime.rs +1 -1
  139. data/bridge/src/test_server.rs +153 -0
  140. data/bridge/src/worker.rs +89 -16
  141. data/lib/gen/temporal/api/command/v1/message_pb.rb +4 -18
  142. data/lib/gen/temporal/api/common/v1/message_pb.rb +4 -0
  143. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +1 -3
  144. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -3
  145. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +2 -0
  146. data/lib/gen/temporal/api/enums/v1/update_pb.rb +6 -4
  147. data/lib/gen/temporal/api/history/v1/message_pb.rb +27 -19
  148. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -0
  149. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +3 -0
  150. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  151. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  152. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  153. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  154. data/lib/gen/temporal/api/update/v1/message_pb.rb +72 -0
  155. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +26 -16
  156. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  157. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  158. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  159. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  160. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  161. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  162. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +27 -21
  163. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +28 -24
  164. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  165. data/lib/temporalio/activity/context.rb +13 -8
  166. data/lib/temporalio/activity/info.rb +1 -1
  167. data/lib/temporalio/bridge/connect_options.rb +15 -0
  168. data/lib/temporalio/bridge/retry_config.rb +24 -0
  169. data/lib/temporalio/bridge/tls_options.rb +19 -0
  170. data/lib/temporalio/client/implementation.rb +8 -8
  171. data/lib/temporalio/connection/retry_config.rb +44 -0
  172. data/lib/temporalio/connection/service.rb +20 -0
  173. data/lib/temporalio/connection/test_service.rb +92 -0
  174. data/lib/temporalio/connection/tls_options.rb +51 -0
  175. data/lib/temporalio/connection/workflow_service.rb +731 -0
  176. data/lib/temporalio/connection.rb +55 -720
  177. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  178. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  179. data/lib/temporalio/interceptor/chain.rb +5 -5
  180. data/lib/temporalio/interceptor/client.rb +8 -4
  181. data/lib/temporalio/interceptor.rb +22 -0
  182. data/lib/temporalio/retry_policy.rb +13 -3
  183. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  184. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  185. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  186. data/lib/temporalio/testing.rb +175 -0
  187. data/lib/temporalio/version.rb +1 -1
  188. data/lib/temporalio/worker/activity_runner.rb +26 -4
  189. data/lib/temporalio/worker/activity_worker.rb +44 -18
  190. data/lib/temporalio/worker/sync_worker.rb +47 -11
  191. data/lib/temporalio/worker.rb +27 -21
  192. data/lib/temporalio/workflow/async.rb +46 -0
  193. data/lib/temporalio/workflow/future.rb +138 -0
  194. data/lib/temporalio/workflow/info.rb +76 -0
  195. data/temporalio.gemspec +4 -3
  196. metadata +67 -17
  197. data/bridge/sdk-core/Cargo.lock +0 -2606
  198. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
  199. data/lib/bridge.so +0 -0
  200. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +0 -25
  201. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +0 -49
  202. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
@@ -1,15 +1,17 @@
1
1
  use assert_matches::assert_matches;
2
2
  use std::{sync::Arc, time::Duration};
3
3
  use temporal_client::{
4
- ListClosedFilters, ListOpenFilters, Namespace, StartTimeFilter, WorkflowClientTrait,
5
- WorkflowExecutionFilter, WorkflowOptions,
4
+ ListClosedFilters, ListOpenFilters, Namespace, RegisterNamespaceOptions, StartTimeFilter,
5
+ WorkflowClientTrait, WorkflowExecutionFilter,
6
6
  };
7
7
  use temporal_sdk_core_protos::coresdk::workflow_activation::{
8
8
  workflow_activation_job, WorkflowActivationJob,
9
9
  };
10
10
  use temporal_sdk_core_test_utils::{
11
- get_integ_server_options, CoreWfStarter, WorkerTestHelpers, NAMESPACE,
11
+ drain_pollers_and_shutdown, get_integ_server_options, CoreWfStarter, WorkerTestHelpers,
12
+ NAMESPACE,
12
13
  };
14
+ use tokio::time::sleep;
13
15
 
14
16
  #[tokio::test]
15
17
  async fn client_list_open_closed_workflow_executions() {
@@ -22,9 +24,7 @@ async fn client_list_open_closed_workflow_executions() {
22
24
  let latest = earliest + Duration::from_secs(60);
23
25
 
24
26
  // start workflow
25
- let run_id = starter
26
- .start_wf_with_id(wf_name.to_owned(), WorkflowOptions::default())
27
- .await;
27
+ let run_id = starter.start_wf_with_id(wf_name.to_owned()).await;
28
28
  let task = core.poll_workflow_activation().await.unwrap();
29
29
  assert_matches!(
30
30
  task.jobs.as_slice(),
@@ -52,28 +52,86 @@ async fn client_list_open_closed_workflow_executions() {
52
52
 
53
53
  // Complete workflow
54
54
  core.complete_execution(&task.run_id).await;
55
+ drain_pollers_and_shutdown(&core).await;
55
56
 
56
- // List above CLOSED workflow
57
- let start_time_filter = StartTimeFilter {
58
- earliest_time: Some(earliest).and_then(|t| t.try_into().ok()),
59
- latest_time: Some(latest).and_then(|t| t.try_into().ok()),
60
- };
61
- let filter = ListClosedFilters::ExecutionFilter(WorkflowExecutionFilter {
62
- workflow_id: wf_name.clone(),
63
- run_id,
64
- });
65
- let closed_workflows = client
66
- .list_closed_workflow_executions(
67
- 1,
68
- Default::default(),
69
- Some(start_time_filter),
70
- Some(filter),
71
- )
57
+ // List above CLOSED workflow. Visibility doesn't always update immediately so we give this a
58
+ // few tries.
59
+ let mut passed = false;
60
+ for _ in 1..=5 {
61
+ let closed_workflows = client
62
+ .list_closed_workflow_executions(
63
+ 1,
64
+ Default::default(),
65
+ Some(StartTimeFilter {
66
+ earliest_time: Some(earliest).and_then(|t| t.try_into().ok()),
67
+ latest_time: Some(latest).and_then(|t| t.try_into().ok()),
68
+ }),
69
+ Some(ListClosedFilters::ExecutionFilter(
70
+ WorkflowExecutionFilter {
71
+ workflow_id: wf_name.clone(),
72
+ run_id: run_id.clone(),
73
+ },
74
+ )),
75
+ )
76
+ .await
77
+ .unwrap();
78
+ if closed_workflows.executions.len() == 1 {
79
+ let workflow = &closed_workflows.executions[0];
80
+ if workflow.execution.as_ref().unwrap().workflow_id == wf_name {
81
+ passed = true;
82
+ break;
83
+ }
84
+ }
85
+ sleep(Duration::from_millis(100)).await;
86
+ }
87
+ assert!(passed);
88
+ }
89
+
90
+ #[tokio::test]
91
+ async fn client_create_namespace() {
92
+ let client = Arc::new(
93
+ get_integ_server_options()
94
+ .connect(NAMESPACE.to_owned(), None, None)
95
+ .await
96
+ .expect("Must connect"),
97
+ );
98
+
99
+ let register_options = RegisterNamespaceOptions::builder()
100
+ .namespace("test-create-namespace")
101
+ .description("it's alive")
102
+ .build()
103
+ .unwrap();
104
+
105
+ client
106
+ .register_namespace(register_options.clone())
72
107
  .await
73
108
  .unwrap();
74
- assert_eq!(closed_workflows.executions.len(), 1);
75
- let workflow = closed_workflows.executions[0].clone();
76
- assert_eq!(workflow.execution.as_ref().unwrap().workflow_id, wf_name);
109
+
110
+ //#Hack, not sure how else to wait for a proper response. RegisterNamespace isn't safe to read
111
+ //after write
112
+ let mut attempts = 0;
113
+ let wait_time = Duration::from_secs(1);
114
+ loop {
115
+ attempts += 1;
116
+ let resp = client
117
+ .describe_namespace(Namespace::Name(register_options.namespace.clone()))
118
+ .await;
119
+
120
+ match resp {
121
+ Ok(n) => {
122
+ let namespace_info = n.namespace_info.unwrap();
123
+ assert_eq!(namespace_info.name, register_options.namespace);
124
+ assert_eq!(namespace_info.description, register_options.description);
125
+ return;
126
+ }
127
+ _ => {
128
+ if attempts == 12 {
129
+ panic!("failed to query registered namespace");
130
+ }
131
+ sleep(wait_time).await
132
+ }
133
+ }
134
+ }
77
135
  }
78
136
 
79
137
  #[tokio::test]
@@ -1,3 +1,4 @@
1
+ use anyhow::anyhow;
1
2
  use assert_matches::assert_matches;
2
3
  use std::time::Duration;
3
4
  use temporal_client::{WfClientExt, WorkflowClientTrait, WorkflowExecutionResult, WorkflowOptions};
@@ -23,10 +24,11 @@ use temporal_sdk_core_protos::{
23
24
  enums::v1::RetryState,
24
25
  failure::v1::{failure::FailureInfo, ActivityFailureInfo, Failure},
25
26
  },
26
- TaskToken,
27
+ TaskToken, DEFAULT_ACTIVITY_TYPE,
27
28
  };
28
29
  use temporal_sdk_core_test_utils::{
29
- init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
30
+ drain_pollers_and_shutdown, init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter,
31
+ WorkerTestHelpers,
30
32
  };
31
33
  use tokio::time::sleep;
32
34
 
@@ -97,7 +99,7 @@ async fn activity_workflow() {
97
99
  assert_matches!(
98
100
  task.variant,
99
101
  Some(act_task::Variant::Start(start_activity)) => {
100
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
102
+ assert_eq!(start_activity.activity_type, DEFAULT_ACTIVITY_TYPE.to_string())
101
103
  }
102
104
  );
103
105
  let response_payload = Payload {
@@ -154,16 +156,78 @@ async fn activity_non_retryable_failure() {
154
156
  )
155
157
  .await
156
158
  .unwrap();
157
- // Poll activity and verify that it's been scheduled with correct parameters
159
+ // Poll activity and verify that it's been scheduled
158
160
  let task = core.poll_activity_task().await.unwrap();
161
+ assert_matches!(task.variant, Some(act_task::Variant::Start(_)));
162
+ // Fail activity with non-retryable error
163
+ let failure = Failure::application_failure("activity failed".to_string(), true);
164
+ core.complete_activity_task(ActivityTaskCompletion {
165
+ task_token: task.task_token,
166
+ result: Some(ActivityExecutionResult::fail(failure.clone())),
167
+ })
168
+ .await
169
+ .unwrap();
170
+ // Poll workflow task and verify that activity has failed.
171
+ let task = core.poll_workflow_activation().await.unwrap();
159
172
  assert_matches!(
160
- task.variant,
161
- Some(act_task::Variant::Start(start_activity)) => {
162
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
173
+ task.jobs.as_slice(),
174
+ [
175
+ WorkflowActivationJob {
176
+ variant: Some(workflow_activation_job::Variant::ResolveActivity(
177
+ ResolveActivity {seq, result: Some(ActivityResolution{
178
+ status: Some(act_res::Status::Failed(activity_result::Failure{
179
+ failure: Some(f),
180
+ }))})}
181
+ )),
182
+ },
183
+ ] => {
184
+ assert_eq!(*seq, 0);
185
+ assert_eq!(f, &Failure{
186
+ message: "Activity task failed".to_owned(),
187
+ cause: Some(Box::new(failure)),
188
+ failure_info: Some(FailureInfo::ActivityFailureInfo(ActivityFailureInfo{
189
+ activity_id: "act-1".to_owned(),
190
+ activity_type: Some(ActivityType {
191
+ name: DEFAULT_ACTIVITY_TYPE.to_owned(),
192
+ }),
193
+ scheduled_event_id: 5,
194
+ started_event_id: 6,
195
+ identity: "integ_tester".to_owned(),
196
+ retry_state: RetryState::NonRetryableFailure as i32,
197
+ })),
198
+ ..Default::default()
199
+ });
163
200
  }
164
201
  );
202
+ core.complete_execution(&task.run_id).await;
203
+ }
204
+
205
+ #[tokio::test]
206
+ async fn activity_non_retryable_failure_with_error() {
207
+ let mut starter = init_core_and_create_wf("activity_non_retryable_failure").await;
208
+ let core = starter.get_worker().await;
209
+ let task_q = starter.get_task_queue();
210
+ let activity_id = "act-1";
211
+ let task = core.poll_workflow_activation().await.unwrap();
212
+ // Complete workflow task and schedule activity
213
+ core.complete_workflow_activation(
214
+ schedule_activity_cmd(
215
+ 0,
216
+ task_q,
217
+ activity_id,
218
+ ActivityCancellationType::TryCancel,
219
+ Duration::from_secs(60),
220
+ Duration::from_secs(60),
221
+ )
222
+ .into_completion(task.run_id),
223
+ )
224
+ .await
225
+ .unwrap();
226
+ // Poll activity and verify that it's been scheduled
227
+ let task = core.poll_activity_task().await.unwrap();
228
+ assert_matches!(task.variant, Some(act_task::Variant::Start(_)));
165
229
  // Fail activity with non-retryable error
166
- let failure = Failure::application_failure("activity failed".to_string(), true);
230
+ let failure = Failure::application_failure_from_error(anyhow!("activity failed"), true);
167
231
  core.complete_activity_task(ActivityTaskCompletion {
168
232
  task_token: task.task_token,
169
233
  result: Some(ActivityExecutionResult::fail(failure.clone())),
@@ -191,7 +255,7 @@ async fn activity_non_retryable_failure() {
191
255
  failure_info: Some(FailureInfo::ActivityFailureInfo(ActivityFailureInfo{
192
256
  activity_id: "act-1".to_owned(),
193
257
  activity_type: Some(ActivityType {
194
- name: "test_activity".to_owned(),
258
+ name: DEFAULT_ACTIVITY_TYPE.to_owned(),
195
259
  }),
196
260
  scheduled_event_id: 5,
197
261
  started_event_id: 6,
@@ -228,12 +292,7 @@ async fn activity_retry() {
228
292
  .unwrap();
229
293
  // Poll activity 1st time
230
294
  let task = core.poll_activity_task().await.unwrap();
231
- assert_matches!(
232
- task.variant,
233
- Some(act_task::Variant::Start(start_activity)) => {
234
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
235
- }
236
- );
295
+ assert_matches!(task.variant, Some(act_task::Variant::Start(_)));
237
296
  // Fail activity with retryable error
238
297
  let failure = Failure::application_failure("activity failed".to_string(), false);
239
298
  core.complete_activity_task(ActivityTaskCompletion {
@@ -244,12 +303,7 @@ async fn activity_retry() {
244
303
  .unwrap();
245
304
  // Poll 2nd time
246
305
  let task = core.poll_activity_task().await.unwrap();
247
- assert_matches!(
248
- task.variant,
249
- Some(act_task::Variant::Start(start_activity)) => {
250
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
251
- }
252
- );
306
+ assert_matches!(task.variant, Some(act_task::Variant::Start(_)));
253
307
  // Complete activity successfully
254
308
  let response_payload = Payload {
255
309
  data: b"hello ".to_vec(),
@@ -308,15 +362,10 @@ async fn activity_cancellation_try_cancel() {
308
362
  )
309
363
  .await
310
364
  .unwrap();
311
- // Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
312
- // complete it in this test as activity is try-cancelled.
365
+ // Poll activity and verify that it's been scheduled, we don't expect to complete it in this
366
+ // test as activity is try-cancelled.
313
367
  let activity_task = core.poll_activity_task().await.unwrap();
314
- assert_matches!(
315
- activity_task.variant,
316
- Some(act_task::Variant::Start(start_activity)) => {
317
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
318
- }
319
- );
368
+ assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
320
369
  // Poll workflow task and verify that activity has failed.
321
370
  let task = core.poll_workflow_activation().await.unwrap();
322
371
  assert_matches!(
@@ -453,15 +502,10 @@ async fn started_activity_timeout() {
453
502
  )
454
503
  .await
455
504
  .unwrap();
456
- // Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
457
- // complete it in this test as activity is timed out after 1 second.
505
+ // Poll activity and verify that it's been scheduled, we don't expect to complete it in this
506
+ // test as activity is timed out after 1 second.
458
507
  let activity_task = core.poll_activity_task().await.unwrap();
459
- assert_matches!(
460
- activity_task.variant,
461
- Some(act_task::Variant::Start(start_activity)) => {
462
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
463
- }
464
- );
508
+ assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
465
509
  let task = core.poll_workflow_activation().await.unwrap();
466
510
  assert_matches!(
467
511
  task.jobs.as_slice(),
@@ -517,15 +561,10 @@ async fn activity_cancellation_wait_cancellation_completed() {
517
561
  )
518
562
  .await
519
563
  .unwrap();
520
- // Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
521
- // complete it in this test as activity is wait-cancelled.
564
+ // Poll activity and verify that it's been scheduled, we don't expect to complete it in this
565
+ // test as activity is wait-cancelled.
522
566
  let activity_task = core.poll_activity_task().await.unwrap();
523
- assert_matches!(
524
- activity_task.variant,
525
- Some(act_task::Variant::Start(start_activity)) => {
526
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
527
- }
528
- );
567
+ assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
529
568
  // Poll workflow task and verify that activity has failed.
530
569
  let task = core.poll_workflow_activation().await.unwrap();
531
570
  assert_matches!(
@@ -584,15 +623,10 @@ async fn activity_cancellation_abandon() {
584
623
  )
585
624
  .await
586
625
  .unwrap();
587
- // Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
588
- // complete it in this test as activity is abandoned.
626
+ // Poll activity and verify that it's been scheduled, we don't expect to complete it in this
627
+ // test as activity is abandoned.
589
628
  let activity_task = core.poll_activity_task().await.unwrap();
590
- assert_matches!(
591
- activity_task.variant,
592
- Some(act_task::Variant::Start(start_activity)) => {
593
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
594
- }
595
- );
629
+ assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
596
630
  // Poll workflow task and verify that activity has failed.
597
631
  let task = core.poll_workflow_activation().await.unwrap();
598
632
  assert_matches!(
@@ -640,14 +674,9 @@ async fn async_activity_completion_workflow() {
640
674
  )
641
675
  .await
642
676
  .unwrap();
643
- // Poll activity and verify that it's been scheduled with correct parameters
677
+ // Poll activity and verify that it's been scheduled
644
678
  let task = core.poll_activity_task().await.unwrap();
645
- assert_matches!(
646
- task.variant,
647
- Some(act_task::Variant::Start(start_activity)) => {
648
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
649
- }
650
- );
679
+ assert_matches!(task.variant, Some(act_task::Variant::Start(_)));
651
680
  let response_payload = Payload {
652
681
  data: b"hello ".to_vec(),
653
682
  metadata: Default::default(),
@@ -712,14 +741,9 @@ async fn activity_cancelled_after_heartbeat_times_out() {
712
741
  )
713
742
  .await
714
743
  .unwrap();
715
- // Poll activity and verify that it's been scheduled with correct parameters
744
+ // Poll activity and verify that it's been scheduled
716
745
  let task = core.poll_activity_task().await.unwrap();
717
- assert_matches!(
718
- task.variant,
719
- Some(act_task::Variant::Start(start_activity)) => {
720
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
721
- }
722
- );
746
+ assert_matches!(task.variant, Some(act_task::Variant::Start(_)));
723
747
  // Delay the heartbeat
724
748
  sleep(Duration::from_secs(2)).await;
725
749
  core.record_activity_heartbeat(ActivityHeartbeat {
@@ -741,7 +765,7 @@ async fn activity_cancelled_after_heartbeat_times_out() {
741
765
  .unwrap();
742
766
 
743
767
  // Verify shutdown completes
744
- core.shutdown().await;
768
+ drain_pollers_and_shutdown(&core).await;
745
769
  // Cleanup just in case
746
770
  starter
747
771
  .get_client()
@@ -822,7 +846,7 @@ async fn it_can_complete_async() {
822
846
  Some(act_res::Status::Completed(activity_result::Success { result })) => result
823
847
  .map(|p| String::from_json_payload(&p).unwrap())
824
848
  .unwrap(),
825
- _ => panic!("activity task failed {:?}", activity_resolution),
849
+ _ => panic!("activity task failed {activity_resolution:?}"),
826
850
  };
827
851
 
828
852
  assert_eq!(&res, async_response);
@@ -33,6 +33,7 @@ async fn cancel_receiver(mut ctx: WfContext) -> WorkflowResult<()> {
33
33
  #[tokio::test]
34
34
  async fn sends_cancel_to_other_wf() {
35
35
  let mut starter = CoreWfStarter::new("sends_cancel_to_other_wf");
36
+ starter.no_remote_activities();
36
37
  let mut worker = starter.worker().await;
37
38
  worker.register_wf("sender", cancel_sender);
38
39
  worker.register_wf("receiver", cancel_receiver);
@@ -1,5 +1,5 @@
1
1
  use std::time::Duration;
2
- use temporal_client::{WorkflowClientTrait, WorkflowOptions};
2
+ use temporal_client::WorkflowClientTrait;
3
3
  use temporal_sdk::{WfContext, WfExitValue, WorkflowResult};
4
4
  use temporal_sdk_core_protos::temporal::api::enums::v1::WorkflowExecutionStatus;
5
5
  use temporal_sdk_core_test_utils::CoreWfStarter;
@@ -21,25 +21,18 @@ async fn cancelled_wf(mut ctx: WfContext) -> WorkflowResult<()> {
21
21
  async fn cancel_during_timer() {
22
22
  let wf_name = "cancel_during_timer";
23
23
  let mut starter = CoreWfStarter::new(wf_name);
24
+ starter.no_remote_activities();
24
25
  let mut worker = starter.worker().await;
25
26
  let client = starter.get_client().await;
26
27
  worker.register_wf(wf_name.to_string(), cancelled_wf);
27
-
28
- worker
29
- .submit_wf(
30
- wf_name.to_owned(),
31
- wf_name.to_owned(),
32
- vec![],
33
- WorkflowOptions::default(),
34
- )
35
- .await
36
- .unwrap();
28
+ starter.start_with_worker(wf_name, &mut worker).await;
29
+ let wf_id = starter.get_task_queue().to_string();
37
30
 
38
31
  let canceller = async {
39
32
  tokio::time::sleep(Duration::from_millis(500)).await;
40
33
  // Cancel the workflow externally
41
34
  client
42
- .cancel_workflow_execution(wf_name.to_string(), None, "Dieee".to_string(), None)
35
+ .cancel_workflow_execution(wf_id.clone(), None, "Dieee".to_string(), None)
43
36
  .await
44
37
  .unwrap();
45
38
  };
@@ -47,7 +40,7 @@ async fn cancel_during_timer() {
47
40
  let (_, res) = tokio::join!(canceller, worker.run_until_done());
48
41
  res.unwrap();
49
42
  let desc = client
50
- .describe_workflow_execution(wf_name.to_string(), None)
43
+ .describe_workflow_execution(wf_id, None)
51
44
  .await
52
45
  .unwrap();
53
46
 
@@ -32,6 +32,7 @@ async fn parent_wf(ctx: WfContext) -> WorkflowResult<()> {
32
32
  #[tokio::test]
33
33
  async fn child_workflow_happy_path() {
34
34
  let mut starter = CoreWfStarter::new("child-workflows");
35
+ starter.no_remote_activities();
35
36
  let mut worker = starter.worker().await;
36
37
 
37
38
  worker.register_wf(PARENT_WF_TYPE.to_string(), parent_wf);
@@ -21,6 +21,7 @@ async fn continue_as_new_wf(ctx: WfContext) -> WorkflowResult<()> {
21
21
  async fn continue_as_new_happy_path() {
22
22
  let wf_name = "continue_as_new_happy_path";
23
23
  let mut starter = CoreWfStarter::new(wf_name);
24
+ starter.no_remote_activities();
24
25
  let mut worker = starter.worker().await;
25
26
  worker.register_wf(wf_name.to_string(), continue_as_new_wf);
26
27
 
@@ -40,11 +41,14 @@ async fn continue_as_new_happy_path() {
40
41
  async fn continue_as_new_multiple_concurrent() {
41
42
  let wf_name = "continue_as_new_multiple_concurrent";
42
43
  let mut starter = CoreWfStarter::new(wf_name);
43
- starter.max_cached_workflows(3).max_wft(3);
44
+ starter
45
+ .no_remote_activities()
46
+ .max_cached_workflows(3)
47
+ .max_wft(3);
44
48
  let mut worker = starter.worker().await;
45
49
  worker.register_wf(wf_name.to_string(), continue_as_new_wf);
46
50
 
47
- let wf_names = (1..=20).map(|i| format!("{}-{}", wf_name, i));
51
+ let wf_names = (1..=20).map(|i| format!("{wf_name}-{i}"));
48
52
  for name in wf_names.clone() {
49
53
  worker
50
54
  .submit_wf(
@@ -2,7 +2,7 @@ use std::{
2
2
  sync::atomic::{AtomicUsize, Ordering},
3
3
  time::Duration,
4
4
  };
5
- use temporal_client::WorkflowOptions;
5
+
6
6
  use temporal_sdk::{ActivityOptions, WfContext, WorkflowResult};
7
7
  use temporal_sdk_core_test_utils::CoreWfStarter;
8
8
 
@@ -36,18 +36,11 @@ pub async fn timer_wf_nondeterministic(ctx: WfContext) -> WorkflowResult<()> {
36
36
  async fn test_determinism_error_then_recovers() {
37
37
  let wf_name = "test_determinism_error_then_recovers";
38
38
  let mut starter = CoreWfStarter::new(wf_name);
39
+ starter.no_remote_activities();
39
40
  let mut worker = starter.worker().await;
40
41
 
41
42
  worker.register_wf(wf_name.to_owned(), timer_wf_nondeterministic);
42
- worker
43
- .submit_wf(
44
- wf_name.to_owned(),
45
- wf_name.to_owned(),
46
- vec![],
47
- WorkflowOptions::default(),
48
- )
49
- .await
50
- .unwrap();
43
+ starter.start_with_worker(wf_name, &mut worker).await;
51
44
  worker.run_until_done().await.unwrap();
52
45
  // 4 because we still add on the 3rd and final attempt
53
46
  assert_eq!(RUN_CT.load(Ordering::Relaxed), 4);