@temporalio/core-bridge 1.13.0 → 1.13.2

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 (181) hide show
  1. package/Cargo.lock +239 -382
  2. package/Cargo.toml +11 -11
  3. package/lib/native.d.ts +10 -3
  4. package/package.json +3 -3
  5. package/releases/aarch64-apple-darwin/index.node +0 -0
  6. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  7. package/releases/x86_64-apple-darwin/index.node +0 -0
  8. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  9. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  10. package/sdk-core/.cargo/config.toml +71 -11
  11. package/sdk-core/.clippy.toml +1 -0
  12. package/sdk-core/.github/workflows/heavy.yml +2 -0
  13. package/sdk-core/.github/workflows/per-pr.yml +50 -18
  14. package/sdk-core/ARCHITECTURE.md +44 -48
  15. package/sdk-core/Cargo.toml +26 -7
  16. package/sdk-core/README.md +4 -0
  17. package/sdk-core/arch_docs/diagrams/TimerMachine_Coverage.puml +14 -0
  18. package/sdk-core/arch_docs/diagrams/initial_event_history.png +0 -0
  19. package/sdk-core/arch_docs/sdks_intro.md +299 -0
  20. package/sdk-core/client/Cargo.toml +8 -7
  21. package/sdk-core/client/src/callback_based.rs +1 -2
  22. package/sdk-core/client/src/lib.rs +485 -299
  23. package/sdk-core/client/src/metrics.rs +32 -8
  24. package/sdk-core/client/src/proxy.rs +124 -5
  25. package/sdk-core/client/src/raw.rs +598 -307
  26. package/sdk-core/client/src/replaceable.rs +253 -0
  27. package/sdk-core/client/src/retry.rs +9 -6
  28. package/sdk-core/client/src/worker_registry/mod.rs +19 -3
  29. package/sdk-core/client/src/workflow_handle/mod.rs +20 -17
  30. package/sdk-core/core/Cargo.toml +100 -31
  31. package/sdk-core/core/src/core_tests/activity_tasks.rs +55 -225
  32. package/sdk-core/core/src/core_tests/mod.rs +2 -8
  33. package/sdk-core/core/src/core_tests/queries.rs +3 -5
  34. package/sdk-core/core/src/core_tests/replay_flag.rs +3 -62
  35. package/sdk-core/core/src/core_tests/updates.rs +4 -5
  36. package/sdk-core/core/src/core_tests/workers.rs +4 -3
  37. package/sdk-core/core/src/core_tests/workflow_cancels.rs +10 -7
  38. package/sdk-core/core/src/core_tests/workflow_tasks.rs +28 -291
  39. package/sdk-core/core/src/ephemeral_server/mod.rs +15 -3
  40. package/sdk-core/core/src/internal_flags.rs +11 -1
  41. package/sdk-core/core/src/lib.rs +50 -36
  42. package/sdk-core/core/src/pollers/mod.rs +5 -5
  43. package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
  44. package/sdk-core/core/src/protosext/mod.rs +13 -5
  45. package/sdk-core/core/src/protosext/protocol_messages.rs +4 -11
  46. package/sdk-core/core/src/retry_logic.rs +256 -108
  47. package/sdk-core/core/src/telemetry/metrics.rs +1 -0
  48. package/sdk-core/core/src/telemetry/mod.rs +8 -2
  49. package/sdk-core/core/src/telemetry/prometheus_meter.rs +2 -2
  50. package/sdk-core/core/src/test_help/integ_helpers.rs +971 -0
  51. package/sdk-core/core/src/test_help/mod.rs +10 -1100
  52. package/sdk-core/core/src/test_help/unit_helpers.rs +218 -0
  53. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +42 -6
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +19 -19
  55. package/sdk-core/core/src/worker/activities.rs +10 -3
  56. package/sdk-core/core/src/worker/client/mocks.rs +3 -3
  57. package/sdk-core/core/src/worker/client.rs +130 -93
  58. package/sdk-core/core/src/worker/heartbeat.rs +12 -13
  59. package/sdk-core/core/src/worker/mod.rs +31 -21
  60. package/sdk-core/core/src/worker/nexus.rs +14 -3
  61. package/sdk-core/core/src/worker/slot_provider.rs +9 -0
  62. package/sdk-core/core/src/worker/tuner.rs +159 -0
  63. package/sdk-core/core/src/worker/workflow/history_update.rs +3 -265
  64. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -54
  65. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -82
  66. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -67
  67. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -192
  68. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -43
  69. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +6 -554
  70. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -71
  71. package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +102 -3
  72. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +10 -539
  73. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -139
  74. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -119
  75. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -63
  76. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +9 -4
  77. package/sdk-core/core/src/worker/workflow/mod.rs +5 -1
  78. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +8 -3
  79. package/sdk-core/core-api/Cargo.toml +4 -4
  80. package/sdk-core/core-api/src/envconfig.rs +153 -54
  81. package/sdk-core/core-api/src/lib.rs +68 -0
  82. package/sdk-core/core-api/src/telemetry/metrics.rs +2 -1
  83. package/sdk-core/core-api/src/telemetry.rs +13 -0
  84. package/sdk-core/core-c-bridge/Cargo.toml +13 -8
  85. package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +184 -22
  86. package/sdk-core/core-c-bridge/src/client.rs +462 -184
  87. package/sdk-core/core-c-bridge/src/envconfig.rs +314 -0
  88. package/sdk-core/core-c-bridge/src/lib.rs +1 -0
  89. package/sdk-core/core-c-bridge/src/random.rs +4 -4
  90. package/sdk-core/core-c-bridge/src/runtime.rs +22 -23
  91. package/sdk-core/core-c-bridge/src/testing.rs +1 -4
  92. package/sdk-core/core-c-bridge/src/tests/context.rs +31 -31
  93. package/sdk-core/core-c-bridge/src/tests/mod.rs +32 -28
  94. package/sdk-core/core-c-bridge/src/tests/utils.rs +7 -7
  95. package/sdk-core/core-c-bridge/src/worker.rs +319 -66
  96. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -1
  97. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +5 -5
  98. package/sdk-core/sdk/Cargo.toml +8 -2
  99. package/sdk-core/sdk/src/activity_context.rs +1 -1
  100. package/sdk-core/sdk/src/app_data.rs +1 -1
  101. package/sdk-core/sdk/src/interceptors.rs +1 -4
  102. package/sdk-core/sdk/src/lib.rs +1 -5
  103. package/sdk-core/sdk/src/workflow_context/options.rs +10 -1
  104. package/sdk-core/sdk/src/workflow_future.rs +1 -1
  105. package/sdk-core/sdk-core-protos/Cargo.toml +6 -6
  106. package/sdk-core/sdk-core-protos/build.rs +10 -23
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/create-release.yml +9 -1
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +254 -5
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +234 -5
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +1 -1
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +6 -0
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -2
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -2
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -6
  115. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  116. package/sdk-core/{test-utils → sdk-core-protos}/src/canned_histories.rs +5 -5
  117. package/sdk-core/sdk-core-protos/src/history_builder.rs +2 -2
  118. package/sdk-core/sdk-core-protos/src/lib.rs +25 -9
  119. package/sdk-core/sdk-core-protos/src/test_utils.rs +89 -0
  120. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -5
  121. package/sdk-core/tests/c_bridge_smoke_test.c +10 -0
  122. package/sdk-core/tests/cloud_tests.rs +10 -8
  123. package/sdk-core/tests/common/http_proxy.rs +134 -0
  124. package/sdk-core/{test-utils/src/lib.rs → tests/common/mod.rs} +214 -281
  125. package/sdk-core/{test-utils/src → tests/common}/workflows.rs +4 -3
  126. package/sdk-core/tests/fuzzy_workflow.rs +1 -1
  127. package/sdk-core/tests/global_metric_tests.rs +8 -7
  128. package/sdk-core/tests/heavy_tests.rs +7 -3
  129. package/sdk-core/tests/integ_tests/client_tests.rs +111 -24
  130. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +14 -9
  131. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +4 -4
  132. package/sdk-core/tests/integ_tests/metrics_tests.rs +114 -14
  133. package/sdk-core/tests/integ_tests/pagination_tests.rs +273 -0
  134. package/sdk-core/tests/integ_tests/polling_tests.rs +311 -93
  135. package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
  136. package/sdk-core/tests/integ_tests/update_tests.rs +13 -7
  137. package/sdk-core/tests/integ_tests/visibility_tests.rs +26 -9
  138. package/sdk-core/tests/integ_tests/worker_tests.rs +668 -13
  139. package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +40 -24
  140. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +244 -11
  141. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
  142. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +78 -2
  143. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +61 -2
  144. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +465 -7
  145. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +41 -2
  146. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +315 -3
  147. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +1 -1
  148. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1990 -14
  149. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +65 -2
  150. package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +123 -23
  151. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +525 -3
  152. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +65 -16
  153. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +32 -23
  154. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +126 -5
  155. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +1 -2
  156. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +124 -8
  157. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +62 -2
  158. package/sdk-core/tests/integ_tests/workflow_tests.rs +67 -8
  159. package/sdk-core/tests/main.rs +26 -17
  160. package/sdk-core/tests/manual_tests.rs +5 -1
  161. package/sdk-core/tests/runner.rs +22 -40
  162. package/sdk-core/tests/shared_tests/mod.rs +1 -1
  163. package/sdk-core/tests/shared_tests/priority.rs +1 -1
  164. package/sdk-core/{core/benches/workflow_replay.rs → tests/workflow_replay_bench.rs} +10 -5
  165. package/src/client.rs +97 -20
  166. package/src/helpers/callbacks.rs +4 -4
  167. package/src/helpers/errors.rs +7 -1
  168. package/src/helpers/handles.rs +1 -0
  169. package/src/helpers/try_from_js.rs +4 -3
  170. package/src/lib.rs +3 -2
  171. package/src/metrics.rs +3 -0
  172. package/src/runtime.rs +5 -2
  173. package/src/worker.rs +9 -12
  174. package/ts/native.ts +13 -3
  175. package/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  176. package/sdk-core/core/src/core_tests/child_workflows.rs +0 -281
  177. package/sdk-core/core/src/core_tests/determinism.rs +0 -318
  178. package/sdk-core/core/src/core_tests/local_activities.rs +0 -1442
  179. package/sdk-core/test-utils/Cargo.toml +0 -38
  180. package/sdk-core/test-utils/src/histfetch.rs +0 -28
  181. package/sdk-core/test-utils/src/interceptors.rs +0 -46
@@ -1,10 +1,25 @@
1
+ use crate::common::{CoreWfStarter, WorkflowHandleExt, mock_sdk, mock_sdk_cfg};
1
2
  use std::{
2
3
  sync::atomic::{AtomicBool, AtomicUsize, Ordering},
3
4
  time::Duration,
4
5
  };
5
- use temporal_sdk::{ActContext, ActivityOptions, WfContext, WorkflowResult};
6
- use temporal_sdk_core_protos::coresdk::AsJsonPayloadExt;
7
- use temporal_sdk_core_test_utils::{CoreWfStarter, WorkflowHandleExt};
6
+ use temporal_client::WorkflowOptions;
7
+ use temporal_sdk::{
8
+ ActContext, ActivityOptions, ChildWorkflowOptions, LocalActivityOptions, WfContext,
9
+ WorkflowResult,
10
+ };
11
+ use temporal_sdk_core::{
12
+ replay::DEFAULT_WORKFLOW_TYPE,
13
+ test_help::{CoreInternalFlags, MockPollCfg, ResponseType, mock_worker_client},
14
+ };
15
+ use temporal_sdk_core_protos::{
16
+ DEFAULT_ACTIVITY_TYPE, TestHistoryBuilder, canned_histories,
17
+ coresdk::AsJsonPayloadExt,
18
+ temporal::api::{
19
+ enums::v1::{EventType, WorkflowTaskFailedCause},
20
+ failure::v1::Failure,
21
+ },
22
+ };
8
23
 
9
24
  static RUN_CT: AtomicUsize = AtomicUsize::new(1);
10
25
 
@@ -83,3 +98,300 @@ async fn task_fail_causes_replay_unset_too_soon() {
83
98
  .await
84
99
  .unwrap();
85
100
  }
101
+
102
+ async fn timer_wf_fails_once(ctx: WfContext) -> WorkflowResult<()> {
103
+ static DID_FAIL: AtomicBool = AtomicBool::new(false);
104
+
105
+ ctx.timer(Duration::from_secs(1)).await;
106
+ if DID_FAIL
107
+ .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
108
+ .is_ok()
109
+ {
110
+ panic!("Ahh");
111
+ }
112
+ Ok(().into())
113
+ }
114
+
115
+ /// Verifies that workflow panics (which in this case the Rust SDK turns into workflow activation
116
+ /// failures) are turned into unspecified WFT failures.
117
+ #[tokio::test]
118
+ async fn test_panic_wf_task_rejected_properly() {
119
+ let wf_id = "fakeid";
120
+ let wf_type = DEFAULT_WORKFLOW_TYPE;
121
+ let t = canned_histories::workflow_fails_with_failure_after_timer("1");
122
+ let mock = mock_worker_client();
123
+ let mut mh = MockPollCfg::from_resp_batches(wf_id, t, [1, 2, 2], mock);
124
+ // We should see one wft failure which has unspecified cause, since panics don't have a defined
125
+ // type.
126
+ mh.num_expected_fails = 1;
127
+ mh.expect_fail_wft_matcher =
128
+ Box::new(|_, cause, _| matches!(cause, WorkflowTaskFailedCause::Unspecified));
129
+ let mut worker = mock_sdk(mh);
130
+
131
+ worker.register_wf(wf_type.to_owned(), timer_wf_fails_once);
132
+ worker
133
+ .submit_wf(
134
+ wf_id.to_owned(),
135
+ wf_type.to_owned(),
136
+ vec![],
137
+ WorkflowOptions::default(),
138
+ )
139
+ .await
140
+ .unwrap();
141
+ worker.run_until_done().await.unwrap();
142
+ }
143
+
144
+ /// Verifies nondeterministic behavior in workflows results in automatic WFT failure with the
145
+ /// appropriate nondeterminism cause.
146
+ #[rstest::rstest]
147
+ #[case::with_cache(true)]
148
+ #[case::without_cache(false)]
149
+ #[tokio::test]
150
+ async fn test_wf_task_rejected_properly_due_to_nondeterminism(#[case] use_cache: bool) {
151
+ let wf_id = "fakeid";
152
+ let wf_type = DEFAULT_WORKFLOW_TYPE;
153
+ let t = canned_histories::single_timer_wf_completes("1");
154
+ let mock = mock_worker_client();
155
+ let mut mh = MockPollCfg::from_resp_batches(
156
+ wf_id,
157
+ t,
158
+ // Two polls are needed, since the first will fail
159
+ [ResponseType::AllHistory, ResponseType::AllHistory],
160
+ mock,
161
+ );
162
+ // We should see one wft failure which has nondeterminism cause
163
+ mh.num_expected_fails = 1;
164
+ mh.expect_fail_wft_matcher =
165
+ Box::new(|_, cause, _| matches!(cause, WorkflowTaskFailedCause::NonDeterministicError));
166
+ let mut worker = mock_sdk_cfg(mh, |cfg| {
167
+ if use_cache {
168
+ cfg.max_cached_workflows = 2;
169
+ }
170
+ });
171
+
172
+ let started_count: &'static _ = Box::leak(Box::new(AtomicUsize::new(0)));
173
+ worker.register_wf(wf_type.to_owned(), move |ctx: WfContext| async move {
174
+ // The workflow is replaying all of history, so the when it schedules an extra timer it
175
+ // should not have, it causes a nondeterminism error.
176
+ if started_count.fetch_add(1, Ordering::Relaxed) == 0 {
177
+ ctx.timer(Duration::from_secs(1)).await;
178
+ }
179
+ ctx.timer(Duration::from_secs(1)).await;
180
+ Ok(().into())
181
+ });
182
+
183
+ worker
184
+ .submit_wf(
185
+ wf_id.to_owned(),
186
+ wf_type.to_owned(),
187
+ vec![],
188
+ WorkflowOptions::default(),
189
+ )
190
+ .await
191
+ .unwrap();
192
+ worker.run_until_done().await.unwrap();
193
+ // Started count is two since we start, restart once due to error, then we unblock the real
194
+ // timer and proceed without restarting
195
+ assert_eq!(2, started_count.load(Ordering::Relaxed));
196
+ }
197
+
198
+ #[rstest::rstest]
199
+ #[tokio::test]
200
+ async fn activity_id_or_type_change_is_nondeterministic(
201
+ #[values(true, false)] use_cache: bool,
202
+ #[values(true, false)] id_change: bool,
203
+ #[values(true, false)] local_act: bool,
204
+ ) {
205
+ let wf_id = "fakeid";
206
+ let wf_type = DEFAULT_WORKFLOW_TYPE;
207
+ let mut t: TestHistoryBuilder = if local_act {
208
+ canned_histories::single_local_activity("1")
209
+ } else {
210
+ canned_histories::single_activity("1")
211
+ };
212
+ t.set_flags_first_wft(&[CoreInternalFlags::IdAndTypeDeterminismChecks as u32], &[]);
213
+ let mock = mock_worker_client();
214
+ let mut mh = MockPollCfg::from_resp_batches(
215
+ wf_id,
216
+ t,
217
+ // Two polls are needed, since the first will fail
218
+ [ResponseType::AllHistory, ResponseType::AllHistory],
219
+ mock,
220
+ );
221
+ // We should see one wft failure which has nondeterminism cause
222
+ mh.num_expected_fails = 1;
223
+ mh.expect_fail_wft_matcher = Box::new(move |_, cause, f| {
224
+ let should_contain = if id_change {
225
+ "does not match activity id"
226
+ } else {
227
+ "does not match activity type"
228
+ };
229
+ matches!(cause, WorkflowTaskFailedCause::NonDeterministicError)
230
+ && matches!(f, Some(Failure {
231
+ message,
232
+ ..
233
+ }) if message.contains(should_contain))
234
+ });
235
+ let mut worker = mock_sdk_cfg(mh, |cfg| {
236
+ if use_cache {
237
+ cfg.max_cached_workflows = 2;
238
+ }
239
+ });
240
+
241
+ worker.register_wf(wf_type.to_owned(), move |ctx: WfContext| async move {
242
+ if local_act {
243
+ ctx.local_activity(if id_change {
244
+ LocalActivityOptions {
245
+ activity_id: Some("I'm bad and wrong!".to_string()),
246
+ activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
247
+ ..Default::default()
248
+ }
249
+ } else {
250
+ LocalActivityOptions {
251
+ activity_type: "not the default act type".to_string(),
252
+ ..Default::default()
253
+ }
254
+ })
255
+ .await;
256
+ } else {
257
+ ctx.activity(if id_change {
258
+ ActivityOptions {
259
+ activity_id: Some("I'm bad and wrong!".to_string()),
260
+ activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
261
+ ..Default::default()
262
+ }
263
+ } else {
264
+ ActivityOptions {
265
+ activity_type: "not the default act type".to_string(),
266
+ ..Default::default()
267
+ }
268
+ })
269
+ .await;
270
+ }
271
+ Ok(().into())
272
+ });
273
+
274
+ worker
275
+ .submit_wf(
276
+ wf_id.to_owned(),
277
+ wf_type.to_owned(),
278
+ vec![],
279
+ WorkflowOptions::default(),
280
+ )
281
+ .await
282
+ .unwrap();
283
+ worker.run_until_done().await.unwrap();
284
+ }
285
+
286
+ #[rstest::rstest]
287
+ #[tokio::test]
288
+ async fn child_wf_id_or_type_change_is_nondeterministic(
289
+ #[values(true, false)] use_cache: bool,
290
+ #[values(true, false)] id_change: bool,
291
+ ) {
292
+ let wf_id = "fakeid";
293
+ let wf_type = DEFAULT_WORKFLOW_TYPE;
294
+ let mut t = canned_histories::single_child_workflow("1");
295
+ t.set_flags_first_wft(&[CoreInternalFlags::IdAndTypeDeterminismChecks as u32], &[]);
296
+ let mock = mock_worker_client();
297
+ let mut mh = MockPollCfg::from_resp_batches(
298
+ wf_id,
299
+ t,
300
+ // Two polls are needed, since the first will fail
301
+ [ResponseType::AllHistory, ResponseType::AllHistory],
302
+ mock,
303
+ );
304
+ // We should see one wft failure which has nondeterminism cause
305
+ mh.num_expected_fails = 1;
306
+ mh.expect_fail_wft_matcher = Box::new(move |_, cause, f| {
307
+ let should_contain = if id_change {
308
+ "does not match child workflow id"
309
+ } else {
310
+ "does not match child workflow type"
311
+ };
312
+ matches!(cause, WorkflowTaskFailedCause::NonDeterministicError)
313
+ && matches!(f, Some(Failure {
314
+ message,
315
+ ..
316
+ }) if message.contains(should_contain))
317
+ });
318
+ let mut worker = mock_sdk_cfg(mh, |cfg| {
319
+ if use_cache {
320
+ cfg.max_cached_workflows = 2;
321
+ }
322
+ });
323
+
324
+ worker.register_wf(wf_type.to_owned(), move |ctx: WfContext| async move {
325
+ ctx.child_workflow(if id_change {
326
+ ChildWorkflowOptions {
327
+ workflow_id: "I'm bad and wrong!".to_string(),
328
+ workflow_type: DEFAULT_ACTIVITY_TYPE.to_string(),
329
+ ..Default::default()
330
+ }
331
+ } else {
332
+ ChildWorkflowOptions {
333
+ workflow_id: "1".to_string(),
334
+ workflow_type: "not the child wf type".to_string(),
335
+ ..Default::default()
336
+ }
337
+ })
338
+ .start(&ctx)
339
+ .await;
340
+ Ok(().into())
341
+ });
342
+
343
+ worker
344
+ .submit_wf(
345
+ wf_id.to_owned(),
346
+ wf_type.to_owned(),
347
+ vec![],
348
+ WorkflowOptions::default(),
349
+ )
350
+ .await
351
+ .unwrap();
352
+ worker.run_until_done().await.unwrap();
353
+ }
354
+
355
+ /// Repros a situation where if, upon completing a task there is some internal error which causes
356
+ /// us to want to auto-fail the workflow task while there is also an outstanding eviction, the wf
357
+ /// would get evicted but then try to send some info down the completion channel afterward, causing
358
+ /// a panic.
359
+ #[tokio::test]
360
+ async fn repro_channel_missing_because_nondeterminism() {
361
+ for _ in 1..50 {
362
+ let wf_id = "fakeid";
363
+ let wf_type = DEFAULT_WORKFLOW_TYPE;
364
+ let mut t = TestHistoryBuilder::default();
365
+ t.add_by_type(EventType::WorkflowExecutionStarted);
366
+ t.add_full_wf_task();
367
+ t.add_has_change_marker("patch-1", false);
368
+ let _ts = t.add_by_type(EventType::TimerStarted);
369
+ t.add_workflow_task_scheduled_and_started();
370
+
371
+ let mock = mock_worker_client();
372
+ let mut mh =
373
+ MockPollCfg::from_resp_batches(wf_id, t, [1.into(), ResponseType::AllHistory], mock);
374
+ mh.num_expected_fails = 1;
375
+ let mut worker = mock_sdk_cfg(mh, |cfg| {
376
+ cfg.max_cached_workflows = 2;
377
+ cfg.ignore_evicts_on_shutdown = false;
378
+ });
379
+
380
+ worker.register_wf(wf_type.to_owned(), move |ctx: WfContext| async move {
381
+ ctx.patched("wrongid");
382
+ ctx.timer(Duration::from_secs(1)).await;
383
+ Ok(().into())
384
+ });
385
+
386
+ worker
387
+ .submit_wf(
388
+ wf_id.to_owned(),
389
+ wf_type.to_owned(),
390
+ vec![],
391
+ WorkflowOptions::default(),
392
+ )
393
+ .await
394
+ .unwrap();
395
+ worker.run_until_done().await.unwrap();
396
+ }
397
+ }
@@ -1,7 +1,7 @@
1
+ use crate::common::{CoreWfStarter, NAMESPACE, get_integ_server_options};
1
2
  use std::time::Duration;
2
3
  use temporal_client::WorkflowClientTrait;
3
4
  use temporal_sdk::{WfContext, WorkflowResult};
4
- use temporal_sdk_core_test_utils::{CoreWfStarter, NAMESPACE, get_integ_server_options};
5
5
 
6
6
  pub(crate) async fn eager_wf(_context: WfContext) -> WorkflowResult<()> {
7
7
  Ok(().into())