@temporalio/core-bridge 0.20.2 → 0.22.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 (50) hide show
  1. package/Cargo.lock +137 -127
  2. package/index.d.ts +7 -2
  3. package/package.json +3 -3
  4. package/releases/aarch64-apple-darwin/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/docker/docker-compose.yaml +5 -4
  9. package/sdk-core/client/Cargo.toml +1 -0
  10. package/sdk-core/client/src/lib.rs +52 -9
  11. package/sdk-core/client/src/raw.rs +9 -1
  12. package/sdk-core/client/src/retry.rs +12 -1
  13. package/sdk-core/client/src/workflow_handle/mod.rs +183 -0
  14. package/sdk-core/core/src/abstractions.rs +10 -3
  15. package/sdk-core/core/src/core_tests/child_workflows.rs +7 -9
  16. package/sdk-core/core/src/core_tests/determinism.rs +8 -19
  17. package/sdk-core/core/src/core_tests/local_activities.rs +22 -32
  18. package/sdk-core/core/src/core_tests/queries.rs +272 -5
  19. package/sdk-core/core/src/core_tests/workers.rs +4 -34
  20. package/sdk-core/core/src/core_tests/workflow_tasks.rs +197 -41
  21. package/sdk-core/core/src/pending_activations.rs +11 -0
  22. package/sdk-core/core/src/telemetry/mod.rs +1 -1
  23. package/sdk-core/core/src/test_help/mod.rs +57 -7
  24. package/sdk-core/core/src/worker/mod.rs +64 -15
  25. package/sdk-core/core/src/workflow/machines/mod.rs +1 -1
  26. package/sdk-core/core/src/workflow/machines/timer_state_machine.rs +2 -2
  27. package/sdk-core/core/src/workflow/machines/workflow_machines.rs +14 -3
  28. package/sdk-core/core/src/workflow/mod.rs +5 -2
  29. package/sdk-core/core/src/workflow/workflow_tasks/cache_manager.rs +47 -2
  30. package/sdk-core/core/src/workflow/workflow_tasks/concurrency_manager.rs +16 -2
  31. package/sdk-core/core/src/workflow/workflow_tasks/mod.rs +252 -125
  32. package/sdk-core/core-api/src/worker.rs +9 -0
  33. package/sdk-core/sdk/Cargo.toml +1 -0
  34. package/sdk-core/sdk/src/activity_context.rs +223 -0
  35. package/sdk-core/sdk/src/interceptors.rs +8 -2
  36. package/sdk-core/sdk/src/lib.rs +167 -122
  37. package/sdk-core/sdk-core-protos/src/history_info.rs +3 -7
  38. package/sdk-core/test-utils/Cargo.toml +1 -0
  39. package/sdk-core/test-utils/src/lib.rs +78 -37
  40. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +11 -4
  41. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +0 -1
  42. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +0 -3
  43. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +33 -17
  44. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +10 -1
  45. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +0 -1
  46. package/sdk-core/tests/integ_tests/workflow_tests.rs +71 -3
  47. package/sdk-core/tests/load_tests.rs +80 -6
  48. package/src/errors.rs +9 -2
  49. package/src/lib.rs +39 -16
  50. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
@@ -1,27 +1,23 @@
1
1
  use crate::{
2
2
  replay::{default_wes_attribs, TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE},
3
- test_help::{build_mock_pollers, mock_worker, MockPollCfg, ResponseType, TEST_Q},
3
+ test_help::{mock_sdk, mock_sdk_cfg, MockPollCfg, ResponseType},
4
4
  worker::client::mocks::mock_workflow_client,
5
5
  };
6
6
  use anyhow::anyhow;
7
7
  use futures::future::join_all;
8
8
  use std::{
9
- sync::{
10
- atomic::{AtomicUsize, Ordering},
11
- Arc,
12
- },
9
+ sync::atomic::{AtomicUsize, Ordering},
13
10
  time::Duration,
14
11
  };
15
12
  use temporal_client::WorkflowOptions;
16
- use temporal_sdk::{LocalActivityOptions, WfContext, WorkflowResult};
13
+ use temporal_sdk::{ActContext, LocalActivityOptions, WfContext, WorkflowResult};
17
14
  use temporal_sdk_core_protos::{
18
15
  coresdk::{common::RetryPolicy, AsJsonPayloadExt},
19
16
  temporal::api::{enums::v1::EventType, failure::v1::Failure},
20
17
  };
21
- use temporal_sdk_core_test_utils::TestWorker;
22
18
  use tokio::sync::Barrier;
23
19
 
24
- async fn echo(e: String) -> anyhow::Result<String> {
20
+ async fn echo(_ctx: ActContext, e: String) -> anyhow::Result<String> {
25
21
  Ok(e)
26
22
  }
27
23
 
@@ -52,12 +48,11 @@ async fn local_act_two_wfts_before_marker(#[case] replay: bool, #[case] cached:
52
48
  vec![1.into(), 2.into(), ResponseType::AllHistory]
53
49
  };
54
50
  let mh = MockPollCfg::from_resp_batches(wf_id, t, resps, mock);
55
- let mut mock = build_mock_pollers(mh);
56
- if cached {
57
- mock.worker_cfg(|cfg| cfg.max_cached_workflows = 1);
58
- }
59
- let core = mock_worker(mock);
60
- let mut worker = TestWorker::new(Arc::new(core), TEST_Q.to_string());
51
+ let mut worker = mock_sdk_cfg(mh, |cfg| {
52
+ if cached {
53
+ cfg.max_cached_workflows = 1;
54
+ }
55
+ });
61
56
 
62
57
  worker.register_wf(
63
58
  DEFAULT_WORKFLOW_TYPE.to_owned(),
@@ -119,12 +114,13 @@ async fn local_act_many_concurrent() {
119
114
  let wf_id = "fakeid";
120
115
  let mock = mock_workflow_client();
121
116
  let mh = MockPollCfg::from_resp_batches(wf_id, t, [1, 2, 3], mock);
122
- let mock = build_mock_pollers(mh);
123
- let core = mock_worker(mock);
124
- let mut worker = TestWorker::new(Arc::new(core), TEST_Q.to_string());
117
+ let mut worker = mock_sdk(mh);
125
118
 
126
119
  worker.register_wf(DEFAULT_WORKFLOW_TYPE.to_owned(), local_act_fanout_wf);
127
- worker.register_activity("echo", |str: String| async move { Ok(str) });
120
+ worker.register_activity(
121
+ "echo",
122
+ |_ctx: ActContext, str: String| async move { Ok(str) },
123
+ );
128
124
  worker
129
125
  .submit_wf(
130
126
  wf_id.to_owned(),
@@ -167,10 +163,9 @@ async fn local_act_heartbeat(#[case] shutdown_middle: bool) {
167
163
  // and might poll an extra time
168
164
  let mut mh = MockPollCfg::from_resp_batches(wf_id, t, [1, 2, 2, 2, 2], mock);
169
165
  mh.enforce_correct_number_of_polls = false;
170
- let mut mock = build_mock_pollers(mh);
171
- mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
172
- let core = Arc::new(mock_worker(mock));
173
- let mut worker = TestWorker::new(core.clone(), TEST_Q.to_string());
166
+ let mut worker = mock_sdk_cfg(mh, |wc| wc.max_cached_workflows = 1);
167
+ let core = worker.orig_core_worker.clone();
168
+
174
169
  let shutdown_barr: &'static Barrier = Box::leak(Box::new(Barrier::new(2)));
175
170
 
176
171
  worker.register_wf(
@@ -185,7 +180,7 @@ async fn local_act_heartbeat(#[case] shutdown_middle: bool) {
185
180
  Ok(().into())
186
181
  },
187
182
  );
188
- worker.register_activity("echo", move |str: String| async move {
183
+ worker.register_activity("echo", move |_ctx: ActContext, str: String| async move {
189
184
  if shutdown_middle {
190
185
  shutdown_barr.wait().await;
191
186
  }
@@ -226,9 +221,7 @@ async fn local_act_fail_and_retry(#[case] eventually_pass: bool) {
226
221
  let wf_id = "fakeid";
227
222
  let mock = mock_workflow_client();
228
223
  let mh = MockPollCfg::from_resp_batches(wf_id, t, [1], mock);
229
- let mock = build_mock_pollers(mh);
230
- let core = mock_worker(mock);
231
- let mut worker = TestWorker::new(Arc::new(core), TEST_Q.to_string());
224
+ let mut worker = mock_sdk(mh);
232
225
 
233
226
  worker.register_wf(
234
227
  DEFAULT_WORKFLOW_TYPE.to_owned(),
@@ -256,7 +249,7 @@ async fn local_act_fail_and_retry(#[case] eventually_pass: bool) {
256
249
  },
257
250
  );
258
251
  let attempts: &'static _ = Box::leak(Box::new(AtomicUsize::new(0)));
259
- worker.register_activity("echo", move |_: String| async move {
252
+ worker.register_activity("echo", move |_ctx: ActContext, _: String| async move {
260
253
  // Succeed on 3rd attempt (which is ==2 since fetch_add returns prev val)
261
254
  if 2 == attempts.fetch_add(1, Ordering::Relaxed) && eventually_pass {
262
255
  Ok(())
@@ -309,10 +302,7 @@ async fn local_act_retry_long_backoff_uses_timer() {
309
302
  [1.into(), 2.into(), ResponseType::AllHistory],
310
303
  mock,
311
304
  );
312
- let mut mock = build_mock_pollers(mh);
313
- mock.worker_cfg(|w| w.max_cached_workflows = 1);
314
- let core = mock_worker(mock);
315
- let mut worker = TestWorker::new(Arc::new(core), TEST_Q.to_string());
305
+ let mut worker = mock_sdk_cfg(mh, |w| w.max_cached_workflows = 1);
316
306
 
317
307
  worker.register_wf(
318
308
  DEFAULT_WORKFLOW_TYPE.to_owned(),
@@ -338,7 +328,7 @@ async fn local_act_retry_long_backoff_uses_timer() {
338
328
  Ok(().into())
339
329
  },
340
330
  );
341
- worker.register_activity("echo", move |_: String| async move {
331
+ worker.register_activity("echo", move |_ctx: ActContext, _: String| async move {
342
332
  Result::<(), _>::Err(anyhow!("Oh no I failed!"))
343
333
  });
344
334
  worker
@@ -11,8 +11,13 @@ use std::{
11
11
  use temporal_sdk_core_api::Worker as WorkerTrait;
12
12
  use temporal_sdk_core_protos::{
13
13
  coresdk::{
14
- workflow_activation::{workflow_activation_job, WorkflowActivationJob},
15
- workflow_commands::{CompleteWorkflowExecution, QueryResult, QuerySuccess},
14
+ workflow_activation::{
15
+ remove_from_cache::EvictionReason, workflow_activation_job, WorkflowActivationJob,
16
+ },
17
+ workflow_commands::{
18
+ ActivityCancellationType, CompleteWorkflowExecution, ContinueAsNewWorkflowExecution,
19
+ QueryResult, QuerySuccess, RequestCancelActivity,
20
+ },
16
21
  workflow_completion::WorkflowActivationCompletion,
17
22
  },
18
23
  temporal::api::{
@@ -21,11 +26,12 @@ use temporal_sdk_core_protos::{
21
26
  history::v1::History,
22
27
  query::v1::WorkflowQuery,
23
28
  workflowservice::v1::{
24
- RespondQueryTaskCompletedResponse, RespondWorkflowTaskCompletedResponse,
29
+ GetWorkflowExecutionHistoryResponse, RespondQueryTaskCompletedResponse,
30
+ RespondWorkflowTaskCompletedResponse,
25
31
  },
26
32
  },
27
33
  };
28
- use temporal_sdk_core_test_utils::start_timer_cmd;
34
+ use temporal_sdk_core_test_utils::{schedule_activity_cmd, start_timer_cmd};
29
35
 
30
36
  #[rstest::rstest]
31
37
  #[case::with_history(true)]
@@ -80,6 +86,10 @@ async fn legacy_query(#[case] include_history: bool) {
80
86
  };
81
87
  let clear_eviction = || async {
82
88
  let t = worker.poll_workflow_activation().await.unwrap();
89
+ assert_matches!(
90
+ t.jobs[0].variant,
91
+ Some(workflow_activation_job::Variant::RemoveFromCache(_))
92
+ );
83
93
  worker
84
94
  .complete_workflow_activation(WorkflowActivationCompletion::empty(t.run_id))
85
95
  .await
@@ -155,7 +165,12 @@ async fn new_queries(#[case] num_queries: usize) {
155
165
  let tasks = VecDeque::from(vec![
156
166
  hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
157
167
  {
158
- let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string());
168
+ let mut pr = hist_to_poll_resp(
169
+ &t,
170
+ wfid.to_owned(),
171
+ ResponseType::OneTask(2),
172
+ TEST_Q.to_string(),
173
+ );
159
174
  pr.queries = HashMap::new();
160
175
  for i in 1..=num_queries {
161
176
  pr.queries.insert(
@@ -381,3 +396,255 @@ async fn legacy_query_after_complete(#[values(false, true)] full_history: bool)
381
396
 
382
397
  core.shutdown().await;
383
398
  }
399
+
400
+ enum QueryHists {
401
+ Empty,
402
+ Full,
403
+ Partial,
404
+ }
405
+ #[rstest::rstest]
406
+ #[tokio::test]
407
+ async fn query_cache_miss_causes_page_fetch_dont_reply_wft_too_early(
408
+ #[values(QueryHists::Empty, QueryHists::Full, QueryHists::Partial)] hist_type: QueryHists,
409
+ ) {
410
+ let wfid = "fake_wf_id";
411
+ let query_resp = "response";
412
+ let t = canned_histories::single_timer("1");
413
+ let full_hist = t.get_full_history_info().unwrap();
414
+ let tasks = VecDeque::from(vec![{
415
+ let mut pr = match hist_type {
416
+ QueryHists::Empty => {
417
+ // Create a no-history poll response. This happens to be easiest to do by just ripping
418
+ // out the history after making a normal one.
419
+ let mut pr = hist_to_poll_resp(
420
+ &t,
421
+ wfid.to_owned(),
422
+ ResponseType::AllHistory,
423
+ TEST_Q.to_string(),
424
+ );
425
+ pr.history = Some(Default::default());
426
+ pr
427
+ }
428
+ QueryHists::Full => hist_to_poll_resp(
429
+ &t,
430
+ wfid.to_owned(),
431
+ ResponseType::AllHistory,
432
+ TEST_Q.to_string(),
433
+ ),
434
+ QueryHists::Partial => {
435
+ // Create a partial task
436
+ hist_to_poll_resp(
437
+ &t,
438
+ wfid.to_owned(),
439
+ ResponseType::OneTask(2),
440
+ TEST_Q.to_string(),
441
+ )
442
+ }
443
+ };
444
+ pr.queries = HashMap::new();
445
+ pr.queries.insert(
446
+ "the-query".to_string(),
447
+ WorkflowQuery {
448
+ query_type: "query-type".to_string(),
449
+ query_args: Some(b"hi".into()),
450
+ header: None,
451
+ },
452
+ );
453
+ pr
454
+ }]);
455
+ let mut mock_client = mock_workflow_client();
456
+ if !matches!(hist_type, QueryHists::Full) {
457
+ mock_client
458
+ .expect_get_workflow_execution_history()
459
+ .returning(move |_, _, _| {
460
+ Ok(GetWorkflowExecutionHistoryResponse {
461
+ history: Some(full_hist.clone().into()),
462
+ ..Default::default()
463
+ })
464
+ });
465
+ }
466
+ mock_client
467
+ .expect_complete_workflow_task()
468
+ .times(1)
469
+ .returning(|resp| {
470
+ // Verify both the complete command and the query response are sent
471
+ assert_eq!(resp.commands.len(), 1);
472
+ assert_eq!(resp.query_responses.len(), 1);
473
+
474
+ Ok(RespondWorkflowTaskCompletedResponse::default())
475
+ });
476
+
477
+ let mut mock = MocksHolder::from_client_with_responses(mock_client, tasks, vec![]);
478
+ mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
479
+ let core = mock_worker(mock);
480
+ let task = core.poll_workflow_activation().await.unwrap();
481
+ // The first task should *only* start the workflow. It should *not* have a query in it, which
482
+ // was the bug. Query should only appear after we have caught up on replay.
483
+ assert_matches!(
484
+ task.jobs.as_slice(),
485
+ [WorkflowActivationJob {
486
+ variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
487
+ }]
488
+ );
489
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
490
+ task.run_id,
491
+ start_timer_cmd(1, Duration::from_secs(1)),
492
+ ))
493
+ .await
494
+ .unwrap();
495
+
496
+ let task = core.poll_workflow_activation().await.unwrap();
497
+ assert_matches!(
498
+ task.jobs.as_slice(),
499
+ [WorkflowActivationJob {
500
+ variant: Some(workflow_activation_job::Variant::FireTimer(_)),
501
+ }]
502
+ );
503
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
504
+ task.run_id,
505
+ CompleteWorkflowExecution { result: None }.into(),
506
+ ))
507
+ .await
508
+ .unwrap();
509
+
510
+ // Now the query shall arrive
511
+ let task = core.poll_workflow_activation().await.unwrap();
512
+ assert_matches!(
513
+ task.jobs[0],
514
+ WorkflowActivationJob {
515
+ variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
516
+ }
517
+ );
518
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
519
+ task.run_id,
520
+ QueryResult {
521
+ query_id: "the-query".to_string(),
522
+ variant: Some(
523
+ QuerySuccess {
524
+ response: Some(query_resp.into()),
525
+ }
526
+ .into(),
527
+ ),
528
+ }
529
+ .into(),
530
+ ))
531
+ .await
532
+ .unwrap();
533
+
534
+ core.shutdown().await;
535
+ }
536
+
537
+ #[tokio::test]
538
+ async fn query_replay_with_continue_as_new_doesnt_reply_empty_command() {
539
+ let wfid = "fake_wf_id";
540
+ let t = canned_histories::single_timer("1");
541
+ let query_with_hist_task = {
542
+ let mut pr = hist_to_poll_resp(
543
+ &t,
544
+ wfid.to_owned(),
545
+ ResponseType::ToTaskNum(1),
546
+ TEST_Q.to_string(),
547
+ );
548
+ pr.queries = HashMap::new();
549
+ pr.queries.insert(
550
+ "the-query".to_string(),
551
+ WorkflowQuery {
552
+ query_type: "query-type".to_string(),
553
+ query_args: Some(b"hi".into()),
554
+ header: None,
555
+ },
556
+ );
557
+ pr
558
+ };
559
+ let tasks = VecDeque::from(vec![query_with_hist_task]);
560
+ let mut mock_client = mock_workflow_client();
561
+ mock_client
562
+ .expect_complete_workflow_task()
563
+ .times(1)
564
+ .returning(|resp| {
565
+ // Verify both the complete command and the query response are sent
566
+ assert_eq!(resp.commands.len(), 1);
567
+ assert_eq!(resp.query_responses.len(), 1);
568
+ Ok(RespondWorkflowTaskCompletedResponse::default())
569
+ });
570
+
571
+ let mut mock = MocksHolder::from_client_with_responses(mock_client, tasks, vec![]);
572
+ mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
573
+ let core = mock_worker(mock);
574
+
575
+ let task = core.poll_workflow_activation().await.unwrap();
576
+ // Scheduling and immediately canceling an activity produces another activation which is
577
+ // important in this repro
578
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
579
+ task.run_id,
580
+ vec![
581
+ schedule_activity_cmd(
582
+ 0,
583
+ "whatever",
584
+ "act-id",
585
+ ActivityCancellationType::TryCancel,
586
+ Duration::from_secs(60),
587
+ Duration::from_secs(60),
588
+ ),
589
+ RequestCancelActivity { seq: 0 }.into(),
590
+ ContinueAsNewWorkflowExecution {
591
+ ..Default::default()
592
+ }
593
+ .into(),
594
+ ],
595
+ ))
596
+ .await
597
+ .unwrap();
598
+
599
+ // Activity unblocked
600
+ let task = core.poll_workflow_activation().await.unwrap();
601
+ assert_matches!(
602
+ task.jobs.as_slice(),
603
+ [WorkflowActivationJob {
604
+ variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
605
+ }]
606
+ );
607
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
608
+ .await
609
+ .unwrap();
610
+
611
+ let task = core.poll_workflow_activation().await.unwrap();
612
+ let query = assert_matches!(
613
+ task.jobs.as_slice(),
614
+ [WorkflowActivationJob {
615
+ variant: Some(workflow_activation_job::Variant::QueryWorkflow(q)),
616
+ }] => q
617
+ );
618
+ // Throw an evict in there. Repro required a pending eviction during complete.
619
+ core.request_wf_eviction(&task.run_id, "I said so", EvictionReason::LangRequested);
620
+
621
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
622
+ task.run_id,
623
+ QueryResult {
624
+ query_id: query.query_id.clone(),
625
+ variant: Some(
626
+ QuerySuccess {
627
+ response: Some("whatever".into()),
628
+ }
629
+ .into(),
630
+ ),
631
+ }
632
+ .into(),
633
+ ))
634
+ .await
635
+ .unwrap();
636
+
637
+ // Need to complete the eviction to finally send commands and finish
638
+ let task = core.poll_workflow_activation().await.unwrap();
639
+ assert_matches!(
640
+ task.jobs.as_slice(),
641
+ [WorkflowActivationJob {
642
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_))
643
+ }]
644
+ );
645
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
646
+ .await
647
+ .unwrap();
648
+
649
+ core.shutdown().await;
650
+ }
@@ -20,38 +20,6 @@ use temporal_sdk_core_protos::{
20
20
  use temporal_sdk_core_test_utils::start_timer_cmd;
21
21
  use tokio::sync::{watch, Barrier};
22
22
 
23
- #[tokio::test]
24
- async fn multi_workers() {
25
- // TODO: Turn this into a test with multiple independent workers
26
- // Make histories for 5 different workflows on 5 different task queues
27
- // let hists = (0..5).into_iter().map(|i| {
28
- // let wf_id = format!("fake-wf-{}", i);
29
- // let hist = canned_histories::single_timer("1");
30
- // FakeWfResponses {
31
- // wf_id,
32
- // hist,
33
- // response_batches: vec![1.into(), 2.into()],
34
- // task_q: format!("q-{}", i),
35
- // }
36
- // });
37
- // let mock = build_multihist_mock_sg(hists, false, None);
38
- //
39
- // let core = &mock_worker(mock);
40
- //
41
- // for i in 0..5 {
42
- // let tq = format!("q-{}", i);
43
- // let res = core.poll_workflow_activation().await.unwrap();
44
- // assert_matches!(
45
- // res.jobs[0].variant,
46
- // Some(workflow_activation_job::Variant::StartWorkflow(_))
47
- // );
48
- // core.complete_workflow_activation(WorkflowActivationCompletion::empty(res.run_id))
49
- // .await
50
- // .unwrap();
51
- // }
52
- // core.shutdown().await;
53
- }
54
-
55
23
  #[tokio::test]
56
24
  async fn after_shutdown_of_worker_get_shutdown_err() {
57
25
  let t = canned_histories::single_timer("1");
@@ -195,7 +163,7 @@ async fn can_shutdown_local_act_only_worker_when_act_polling() {
195
163
  }
196
164
 
197
165
  #[tokio::test]
198
- async fn complete_with_task_not_found_during_shutdwn() {
166
+ async fn complete_with_task_not_found_during_shutdown() {
199
167
  let t = canned_histories::single_timer("1");
200
168
  let mut mock = mock_workflow_client();
201
169
  mock.expect_complete_workflow_task()
@@ -236,5 +204,7 @@ async fn complete_with_task_not_found_during_shutdwn() {
236
204
  complete_order.borrow_mut().push(1);
237
205
  };
238
206
  tokio::join!(shutdown_fut, poll_fut, complete_fut);
239
- assert_eq!(&complete_order.into_inner(), &[1, 2, 3])
207
+ // Shutdown will currently complete first before the actual eviction reply since the
208
+ // workflow task is marked complete as soon as we get not found back from the server.
209
+ assert_eq!(&complete_order.into_inner(), &[1, 3, 2])
240
210
  }