@temporalio/core-bridge 1.11.0 → 1.11.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 (75) hide show
  1. package/Cargo.lock +86 -88
  2. package/lib/index.d.ts +3 -0
  3. package/lib/index.js.map +1 -1
  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/.github/workflows/per-pr.yml +7 -1
  11. package/sdk-core/Cargo.toml +1 -1
  12. package/sdk-core/client/Cargo.toml +3 -3
  13. package/sdk-core/client/src/lib.rs +1 -1
  14. package/sdk-core/client/src/metrics.rs +2 -2
  15. package/sdk-core/client/src/raw.rs +39 -13
  16. package/sdk-core/client/src/retry.rs +108 -62
  17. package/sdk-core/client/src/workflow_handle/mod.rs +1 -2
  18. package/sdk-core/core/Cargo.toml +4 -5
  19. package/sdk-core/core/src/abstractions.rs +2 -3
  20. package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
  21. package/sdk-core/core/src/core_tests/local_activities.rs +2 -2
  22. package/sdk-core/core/src/core_tests/queries.rs +8 -4
  23. package/sdk-core/core/src/core_tests/updates.rs +2 -2
  24. package/sdk-core/core/src/core_tests/workflow_cancels.rs +3 -3
  25. package/sdk-core/core/src/core_tests/workflow_tasks.rs +55 -54
  26. package/sdk-core/core/src/ephemeral_server/mod.rs +5 -3
  27. package/sdk-core/core/src/protosext/mod.rs +3 -0
  28. package/sdk-core/core/src/telemetry/mod.rs +0 -8
  29. package/sdk-core/core/src/telemetry/otel.rs +7 -3
  30. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +11 -0
  31. package/sdk-core/core/src/worker/activities.rs +1 -1
  32. package/sdk-core/core/src/worker/mod.rs +6 -6
  33. package/sdk-core/core/src/worker/slot_provider.rs +4 -3
  34. package/sdk-core/core/src/worker/tuner/resource_based.rs +1 -1
  35. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +28 -2
  36. package/sdk-core/core/src/worker/workflow/history_update.rs +2 -2
  37. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +8 -5
  38. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -1
  39. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -1
  40. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +7 -7
  41. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +10 -15
  42. package/sdk-core/core/src/worker/workflow/machines/mod.rs +1 -1
  43. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +3 -2
  44. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -1
  45. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +4 -4
  46. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +30 -20
  47. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +2 -2
  48. package/sdk-core/core/src/worker/workflow/managed_run.rs +20 -4
  49. package/sdk-core/core/src/worker/workflow/mod.rs +33 -29
  50. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +2 -2
  51. package/sdk-core/core-api/src/telemetry.rs +1 -0
  52. package/sdk-core/docker/docker-compose-telem.yaml +4 -4
  53. package/sdk-core/etc/otel-collector-config.yaml +12 -9
  54. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +2 -2
  55. package/sdk-core/sdk/src/lib.rs +30 -3
  56. package/sdk-core/sdk/src/workflow_context.rs +15 -2
  57. package/sdk-core/sdk/src/workflow_future.rs +28 -8
  58. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +31 -12
  59. package/sdk-core/sdk-core-protos/src/lib.rs +104 -63
  60. package/sdk-core/test-utils/src/lib.rs +4 -3
  61. package/sdk-core/tests/integ_tests/client_tests.rs +36 -7
  62. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -1
  63. package/sdk-core/tests/integ_tests/metrics_tests.rs +50 -4
  64. package/sdk-core/tests/integ_tests/queries_tests.rs +95 -62
  65. package/sdk-core/tests/integ_tests/update_tests.rs +16 -9
  66. package/sdk-core/tests/integ_tests/visibility_tests.rs +1 -1
  67. package/sdk-core/tests/integ_tests/worker_tests.rs +82 -1
  68. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +46 -8
  69. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +81 -2
  70. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +139 -4
  71. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +43 -28
  72. package/sdk-core/tests/integ_tests/workflow_tests.rs +2 -1
  73. package/sdk-core/tests/main.rs +28 -19
  74. package/sdk-core/tests/runner.rs +7 -2
  75. package/ts/index.ts +3 -0
@@ -42,8 +42,8 @@ use temporal_sdk_core_protos::{
42
42
  activity_result::{self as ar, activity_resolution, ActivityResolution},
43
43
  common::VersioningIntent,
44
44
  workflow_activation::{
45
- remove_from_cache::EvictionReason, workflow_activation_job, FireTimer, ResolveActivity,
46
- StartWorkflow, UpdateRandomSeed, WorkflowActivationJob,
45
+ remove_from_cache::EvictionReason, workflow_activation_job, FireTimer,
46
+ InitializeWorkflow, ResolveActivity, UpdateRandomSeed, WorkflowActivationJob,
47
47
  },
48
48
  workflow_commands::{
49
49
  update_response::Response, workflow_command, ActivityCancellationType, CancelTimer,
@@ -112,7 +112,7 @@ async fn single_timer(#[case] worker: Worker, #[case] evict: WorkflowCachingPoli
112
112
  evict,
113
113
  &[
114
114
  gen_assert_and_reply(
115
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
115
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
116
116
  vec![start_timer_cmd(1, Duration::from_secs(1))],
117
117
  ),
118
118
  gen_assert_and_reply(
@@ -125,10 +125,10 @@ async fn single_timer(#[case] worker: Worker, #[case] evict: WorkflowCachingPoli
125
125
  }
126
126
 
127
127
  #[rstest(worker,
128
- case::incremental(single_activity_setup(&[1, 2])),
129
- case::incremental_activity_failure(single_activity_failure_setup(&[1, 2])),
130
- case::replay(single_activity_setup(&[2])),
131
- case::replay_activity_failure(single_activity_failure_setup(&[2]))
128
+ case::incremental(single_activity_setup(&[1, 2])),
129
+ case::incremental_activity_failure(single_activity_failure_setup(&[1, 2])),
130
+ case::replay(single_activity_setup(&[2])),
131
+ case::replay_activity_failure(single_activity_failure_setup(&[2]))
132
132
  )]
133
133
  #[tokio::test]
134
134
  async fn single_activity_completion(worker: Worker) {
@@ -137,7 +137,7 @@ async fn single_activity_completion(worker: Worker) {
137
137
  NonSticky,
138
138
  &[
139
139
  gen_assert_and_reply(
140
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
140
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
141
141
  vec![ScheduleActivity {
142
142
  activity_id: "fake_activity".to_string(),
143
143
  ..default_act_sched()
@@ -171,7 +171,7 @@ async fn parallel_timer_test_across_wf_bridge(hist_batches: &'static [usize]) {
171
171
  NonSticky,
172
172
  &[
173
173
  gen_assert_and_reply(
174
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
174
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
175
175
  vec![
176
176
  start_timer_cmd(timer_1_id, Duration::from_secs(1)),
177
177
  start_timer_cmd(timer_2_id, Duration::from_secs(1)),
@@ -223,7 +223,7 @@ async fn timer_cancel(hist_batches: &'static [usize]) {
223
223
  NonSticky,
224
224
  &[
225
225
  gen_assert_and_reply(
226
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
226
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
227
227
  vec![
228
228
  start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
229
229
  start_timer_cmd(timer_id, Duration::from_secs(1)),
@@ -260,7 +260,7 @@ async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usiz
260
260
  NonSticky,
261
261
  &[
262
262
  gen_assert_and_reply(
263
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
263
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
264
264
  vec![ScheduleActivity {
265
265
  seq: activity_seq,
266
266
  activity_id: activity_id.to_string(),
@@ -297,7 +297,7 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
297
297
  NonSticky,
298
298
  &[
299
299
  gen_assert_and_reply(
300
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
300
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
301
301
  vec![ScheduleActivity {
302
302
  seq: activity_seq,
303
303
  activity_id: activity_id.to_string(),
@@ -319,7 +319,7 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
319
319
  status: Some(activity_resolution::Status::Failed(ar::Failure {
320
320
  failure: Some(failure)
321
321
  })),
322
- })
322
+ }), ..
323
323
  }
324
324
  )),
325
325
  }
@@ -350,7 +350,7 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
350
350
  NonSticky,
351
351
  &[
352
352
  gen_assert_and_reply(
353
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
353
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
354
354
  vec![ScheduleActivity {
355
355
  seq: activity_seq,
356
356
  activity_id: activity_seq.to_string(),
@@ -361,7 +361,7 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
361
361
  // Activity is getting resolved right away as it has been timed out.
362
362
  gen_assert_and_reply(
363
363
  &|res| {
364
- assert_matches!(
364
+ assert_matches!(
365
365
  res.jobs.as_slice(),
366
366
  [
367
367
  WorkflowActivationJob {
@@ -372,7 +372,7 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
372
372
  status: Some(activity_resolution::Status::Failed(ar::Failure {
373
373
  failure: Some(failure)
374
374
  })),
375
- })
375
+ }), ..
376
376
  }
377
377
  )),
378
378
  }
@@ -405,7 +405,7 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
405
405
  NonSticky,
406
406
  &[
407
407
  gen_assert_and_reply(
408
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
408
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
409
409
  vec![ScheduleActivity {
410
410
  seq: activity_seq,
411
411
  activity_id: activity_id.to_string(),
@@ -421,10 +421,10 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
421
421
  gen_assert_and_reply(
422
422
  &job_assert!(workflow_activation_job::Variant::ResolveActivity(
423
423
  ResolveActivity {
424
- seq: _,
425
424
  result: Some(ActivityResolution {
426
425
  status: Some(activity_resolution::Status::Cancelled(..)),
427
- })
426
+ }),
427
+ ..
428
428
  }
429
429
  )),
430
430
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -557,7 +557,7 @@ async fn verify_activity_cancellation(
557
557
  NonSticky,
558
558
  &[
559
559
  gen_assert_and_reply(
560
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
560
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
561
561
  vec![ScheduleActivity {
562
562
  seq: activity_seq,
563
563
  activity_id: activity_seq.to_string(),
@@ -574,10 +574,10 @@ async fn verify_activity_cancellation(
574
574
  gen_assert_and_reply(
575
575
  &job_assert!(workflow_activation_job::Variant::ResolveActivity(
576
576
  ResolveActivity {
577
- seq: _,
578
577
  result: Some(ActivityResolution {
579
578
  status: Some(activity_resolution::Status::Cancelled(..)),
580
- })
579
+ }),
580
+ ..
581
581
  }
582
582
  )),
583
583
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -625,7 +625,7 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, wo
625
625
  NonSticky,
626
626
  &[
627
627
  gen_assert_and_reply(
628
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
628
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
629
629
  vec![ScheduleActivity {
630
630
  seq: activity_id,
631
631
  activity_id: activity_id.to_string(),
@@ -647,10 +647,10 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, wo
647
647
  gen_assert_and_reply(
648
648
  &job_assert!(workflow_activation_job::Variant::ResolveActivity(
649
649
  ResolveActivity {
650
- seq: _,
651
650
  result: Some(ActivityResolution {
652
651
  status: Some(activity_resolution::Status::Cancelled(..)),
653
- })
652
+ }),
653
+ ..
654
654
  }
655
655
  )),
656
656
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -682,8 +682,8 @@ async fn workflow_update_random_seed_on_workflow_reset() {
682
682
  assert_matches!(
683
683
  res.jobs.as_slice(),
684
684
  [WorkflowActivationJob {
685
- variant: Some(workflow_activation_job::Variant::StartWorkflow(
686
- StartWorkflow{randomness_seed, ..}
685
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(
686
+ InitializeWorkflow{randomness_seed, ..}
687
687
  )),
688
688
  }] => {
689
689
  randomness_seed_from_start.store(*randomness_seed, Ordering::SeqCst);
@@ -692,17 +692,19 @@ async fn workflow_update_random_seed_on_workflow_reset() {
692
692
  },
693
693
  vec![start_timer_cmd(timer_1_id, Duration::from_secs(1))],
694
694
  ),
695
+ // The random seed update should always be the first job
695
696
  gen_assert_and_reply(
696
697
  &|res| {
697
698
  assert_matches!(
698
699
  res.jobs.as_slice(),
699
700
  [WorkflowActivationJob {
700
- variant: Some(workflow_activation_job::Variant::FireTimer(_),),
701
- },
702
- WorkflowActivationJob {
703
701
  variant: Some(workflow_activation_job::Variant::UpdateRandomSeed(
704
702
  UpdateRandomSeed{randomness_seed})),
705
- }] => {
703
+ },
704
+ WorkflowActivationJob {
705
+ variant: Some(workflow_activation_job::Variant::FireTimer(_),),
706
+ },
707
+ ] => {
706
708
  assert_ne!(randomness_seed_from_start.load(Ordering::SeqCst),
707
709
  *randomness_seed);
708
710
  }
@@ -731,7 +733,7 @@ async fn cancel_timer_before_sent_wf_bridge() {
731
733
  &core,
732
734
  NonSticky,
733
735
  &[gen_assert_and_reply(
734
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
736
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
735
737
  vec![
736
738
  start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
737
739
  CancelTimer {
@@ -802,7 +804,7 @@ async fn simple_timer_fail_wf_execution(hist_batches: &'static [usize]) {
802
804
  NonSticky,
803
805
  &[
804
806
  gen_assert_and_reply(
805
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
807
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
806
808
  vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
807
809
  ),
808
810
  gen_assert_and_reply(
@@ -833,7 +835,7 @@ async fn two_signals(hist_batches: &'static [usize]) {
833
835
  NonSticky,
834
836
  &[
835
837
  gen_assert_and_reply(
836
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
838
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
837
839
  // Task is completed with no commands
838
840
  vec![],
839
841
  ),
@@ -957,7 +959,7 @@ async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
957
959
  NonSticky,
958
960
  &[
959
961
  gen_assert_and_reply(
960
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
962
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
961
963
  // Start timer and activity
962
964
  vec![
963
965
  ScheduleActivity {
@@ -1003,7 +1005,7 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
1003
1005
  NonSticky,
1004
1006
  &[
1005
1007
  gen_assert_and_reply(
1006
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
1008
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
1007
1009
  vec![ScheduleActivity {
1008
1010
  seq: activity_id,
1009
1011
  activity_id: "act-1".to_string(),
@@ -1061,7 +1063,7 @@ async fn lots_of_workflows() {
1061
1063
  while let Ok(wft) = worker.poll_workflow_activation().await {
1062
1064
  let job = &wft.jobs[0];
1063
1065
  let reply = match job.variant {
1064
- Some(workflow_activation_job::Variant::StartWorkflow(_)) => {
1066
+ Some(workflow_activation_job::Variant::InitializeWorkflow(_)) => {
1065
1067
  start_timer_cmd(1, Duration::from_secs(1))
1066
1068
  }
1067
1069
  Some(workflow_activation_job::Variant::RemoveFromCache(_)) => {
@@ -1104,7 +1106,7 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
1104
1106
  NonSticky,
1105
1107
  &[
1106
1108
  gen_assert_and_reply(
1107
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
1109
+ &job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
1108
1110
  vec![ScheduleActivity {
1109
1111
  seq: activity_id,
1110
1112
  activity_id: activity_id.to_string(),
@@ -1226,7 +1228,7 @@ async fn new_server_work_while_eviction_outstanding_doesnt_overwrite_activation(
1226
1228
  let start_again = core.poll_workflow_activation().await.unwrap();
1227
1229
  assert_matches!(
1228
1230
  start_again.jobs[0].variant,
1229
- Some(workflow_activation_job::Variant::StartWorkflow(_))
1231
+ Some(workflow_activation_job::Variant::InitializeWorkflow(_))
1230
1232
  );
1231
1233
  }
1232
1234
 
@@ -1441,7 +1443,7 @@ async fn lang_slower_than_wft_timeouts() {
1441
1443
  let start_again = core.poll_workflow_activation().await.unwrap();
1442
1444
  assert_matches!(
1443
1445
  start_again.jobs[0].variant,
1444
- Some(workflow_activation_job::Variant::StartWorkflow(_))
1446
+ Some(workflow_activation_job::Variant::InitializeWorkflow(_))
1445
1447
  );
1446
1448
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1447
1449
  start_again.run_id,
@@ -1602,7 +1604,7 @@ async fn cache_miss_will_fetch_history() {
1602
1604
  assert_matches!(
1603
1605
  activation.jobs.as_slice(),
1604
1606
  [WorkflowActivationJob {
1605
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
1607
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
1606
1608
  }]
1607
1609
  );
1608
1610
  // Force an eviction (before complete matters, so that we will be sure the eviction is queued
@@ -1631,7 +1633,7 @@ async fn cache_miss_will_fetch_history() {
1631
1633
  assert_matches!(
1632
1634
  activation.jobs.as_slice(),
1633
1635
  [WorkflowActivationJob {
1634
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
1636
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
1635
1637
  }]
1636
1638
  );
1637
1639
  }
@@ -1829,7 +1831,7 @@ async fn poll_faster_than_complete_wont_overflow_cache() {
1829
1831
  for (i, p_res) in [&p1, &p2, &p3].into_iter().enumerate() {
1830
1832
  assert_matches!(
1831
1833
  &p_res.jobs[0].variant,
1832
- Some(workflow_activation_job::Variant::StartWorkflow(sw))
1834
+ Some(workflow_activation_job::Variant::InitializeWorkflow(sw))
1833
1835
  if sw.workflow_id == format!("wf-{}", i + 1)
1834
1836
  );
1835
1837
  }
@@ -1874,7 +1876,7 @@ async fn poll_faster_than_complete_wont_overflow_cache() {
1874
1876
  let res = core.poll_workflow_activation().await.unwrap();
1875
1877
  assert_matches!(
1876
1878
  &res.jobs[0].variant,
1877
- Some(workflow_activation_job::Variant::StartWorkflow(sw))
1879
+ Some(workflow_activation_job::Variant::InitializeWorkflow(sw))
1878
1880
  if sw.workflow_id == format!("wf-{}", 4)
1879
1881
  );
1880
1882
  res
@@ -1919,7 +1921,7 @@ async fn poll_faster_than_complete_wont_overflow_cache() {
1919
1921
  let res = core.poll_workflow_activation().await.unwrap();
1920
1922
  assert_matches!(
1921
1923
  &res.jobs[0].variant,
1922
- Some(workflow_activation_job::Variant::StartWorkflow(sw))
1924
+ Some(workflow_activation_job::Variant::InitializeWorkflow(sw))
1923
1925
  if sw.workflow_id == "wf-5"
1924
1926
  );
1925
1927
  };
@@ -2004,7 +2006,7 @@ async fn autocompletes_wft_no_work() {
2004
2006
  assert_matches!(
2005
2007
  act.jobs.as_slice(),
2006
2008
  [WorkflowActivationJob {
2007
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
2009
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
2008
2010
  }]
2009
2011
  );
2010
2012
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
@@ -2187,7 +2189,7 @@ async fn ignorable_events_are_ok(#[values(true, false)] attribs_unset: bool) {
2187
2189
  let act = core.poll_workflow_activation().await.unwrap();
2188
2190
  assert_matches!(
2189
2191
  act.jobs[0].variant,
2190
- Some(workflow_activation_job::Variant::StartWorkflow(_))
2192
+ Some(workflow_activation_job::Variant::InitializeWorkflow(_))
2191
2193
  );
2192
2194
  }
2193
2195
 
@@ -2235,7 +2237,7 @@ async fn fetching_to_continue_replay_works() {
2235
2237
  let act = core.poll_workflow_activation().await.unwrap();
2236
2238
  assert_matches!(
2237
2239
  act.jobs[0].variant,
2238
- Some(workflow_activation_job::Variant::StartWorkflow(_))
2240
+ Some(workflow_activation_job::Variant::InitializeWorkflow(_))
2239
2241
  );
2240
2242
  core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
2241
2243
  .await
@@ -2286,7 +2288,7 @@ async fn fetching_error_evicts_wf() {
2286
2288
  let act = core.poll_workflow_activation().await.unwrap();
2287
2289
  assert_matches!(
2288
2290
  act.jobs[0].variant,
2289
- Some(workflow_activation_job::Variant::StartWorkflow(_))
2291
+ Some(workflow_activation_job::Variant::InitializeWorkflow(_))
2290
2292
  );
2291
2293
  core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
2292
2294
  .await
@@ -2441,10 +2443,10 @@ async fn lang_internal_flag_with_update() {
2441
2443
  act.jobs.as_slice(),
2442
2444
  [
2443
2445
  WorkflowActivationJob {
2444
- variant: Some(workflow_activation_job::Variant::DoUpdate(_)),
2446
+ variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
2445
2447
  },
2446
2448
  WorkflowActivationJob {
2447
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
2449
+ variant: Some(workflow_activation_job::Variant::DoUpdate(_)),
2448
2450
  },
2449
2451
  ]
2450
2452
  );
@@ -2639,14 +2641,13 @@ async fn jobs_are_in_appropriate_order() {
2639
2641
  let core = mock_worker(mock);
2640
2642
 
2641
2643
  let act = core.poll_workflow_activation().await.unwrap();
2642
- // Patch notifications always come first
2643
2644
  assert_matches!(
2644
2645
  act.jobs[0].variant.as_ref().unwrap(),
2645
- workflow_activation_job::Variant::NotifyHasPatch(_)
2646
+ workflow_activation_job::Variant::InitializeWorkflow(_)
2646
2647
  );
2647
2648
  assert_matches!(
2648
2649
  act.jobs[1].variant.as_ref().unwrap(),
2649
- workflow_activation_job::Variant::StartWorkflow(_)
2650
+ workflow_activation_job::Variant::NotifyHasPatch(_)
2650
2651
  );
2651
2652
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
2652
2653
  act.run_id,
@@ -46,7 +46,7 @@ pub struct TemporalDevServerConfig {
46
46
  /// Log format and level
47
47
  #[builder(default = "(\"pretty\".to_owned(), \"warn\".to_owned())")]
48
48
  pub log: (String, String),
49
- /// Additional arguments to Temporalite.
49
+ /// Additional arguments to Temporal dev server.
50
50
  #[builder(default)]
51
51
  pub extra_args: Vec<String>,
52
52
  }
@@ -567,8 +567,10 @@ async fn download_and_extract(
567
567
  #[cfg(test)]
568
568
  mod tests {
569
569
  use super::get_free_port;
570
- use std::collections::HashSet;
571
- use std::net::{TcpListener, TcpStream};
570
+ use std::{
571
+ collections::HashSet,
572
+ net::{TcpListener, TcpStream},
573
+ };
572
574
 
573
575
  #[test]
574
576
  fn get_free_port_no_double() {
@@ -109,6 +109,9 @@ impl TryFrom<PollWorkflowTaskQueueResponse> for ValidPollWFTQResponse {
109
109
  messages,
110
110
  ..
111
111
  } => {
112
+ if task_token.is_empty() {
113
+ return Err(anyhow!("missing task token"));
114
+ }
112
115
  let query_requests = queries
113
116
  .into_iter()
114
117
  .map(|(id, q)| query_to_job(id, q))
@@ -160,15 +160,7 @@ impl CoreTelemetry for TelemetryInstance {
160
160
  ///
161
161
  /// See [TelemetryOptions] docs for more on configuration.
162
162
  pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyhow::Error> {
163
- // This is a bit odd, but functional. It's desirable to create a separate tokio runtime for
164
- // metrics handling, since tests typically use a single-threaded runtime and initializing
165
- // pipeline requires us to know if the runtime is single or multithreaded, we will crash
166
- // in one case or the other. There does not seem to be a way to tell from the current runtime
167
- // handle if it is single or multithreaded. Additionally, we can isolate metrics work this
168
- // way which is nice.
169
- // Parts of telem dat ====
170
163
  let mut logs_out = None;
171
- // =======================
172
164
 
173
165
  // Tracing subscriber layers =========
174
166
  let mut console_pretty_layer = None;
@@ -35,7 +35,7 @@ use temporal_sdk_core_api::telemetry::{
35
35
  MetricTemporality, OtelCollectorOptions, PrometheusExporterOptions,
36
36
  };
37
37
  use tokio::task::AbortHandle;
38
- use tonic::metadata::MetadataMap;
38
+ use tonic::{metadata::MetadataMap, transport::ClientTlsConfig};
39
39
 
40
40
  /// Chooses appropriate aggregators for our metrics
41
41
  #[derive(Debug, Clone)]
@@ -160,8 +160,12 @@ impl<U> MemoryGauge<U> {
160
160
  pub fn build_otlp_metric_exporter(
161
161
  opts: OtelCollectorOptions,
162
162
  ) -> Result<CoreOtelMeter, anyhow::Error> {
163
- let exporter = opentelemetry_otlp::TonicExporterBuilder::default()
164
- .with_endpoint(opts.url.to_string())
163
+ let mut exporter =
164
+ opentelemetry_otlp::TonicExporterBuilder::default().with_endpoint(opts.url.to_string());
165
+ if opts.url.scheme() == "https" || opts.url.scheme() == "grpcs" {
166
+ exporter = exporter.with_tls_config(ClientTlsConfig::new().with_native_roots());
167
+ }
168
+ let exporter = exporter
165
169
  .with_metadata(MetadataMap::from_headers((&opts.headers).try_into()?))
166
170
  .build_metrics_exporter(
167
171
  Box::new(SDKAggSelector::new(opts.use_seconds_for_durations)),
@@ -35,6 +35,10 @@ pub(crate) fn new_activity_task_poller(
35
35
  state.metrics.act_poll_timeout();
36
36
  continue;
37
37
  }
38
+ if let Some(reason) = validate_activity_task(&resp) {
39
+ warn!("Received invalid activity task ({}): {:?}", reason, &resp);
40
+ continue;
41
+ }
38
42
  Some(Ok(PermittedTqResp { permit, resp }))
39
43
  }
40
44
  Some(Err(e)) => {
@@ -65,3 +69,10 @@ pub(crate) fn new_activity_task_poller(
65
69
  }
66
70
  })
67
71
  }
72
+
73
+ fn validate_activity_task(task: &PollActivityTaskQueueResponse) -> Option<&'static str> {
74
+ if task.task_token.is_empty() {
75
+ return Some("missing task token");
76
+ }
77
+ None
78
+ }
@@ -506,7 +506,7 @@ where
506
506
  )))
507
507
  }
508
508
  } else {
509
- debug!(task_token = ?next_pc.task_token,
509
+ debug!(task_token = %next_pc.task_token,
510
510
  "Unknown activity task when issuing cancel");
511
511
  // If we can't find the activity here, it's already been completed,
512
512
  // in which case issuing a cancel again is pointless.
@@ -587,16 +587,16 @@ impl Worker {
587
587
  /// Attempt to record an activity heartbeat
588
588
  pub(crate) fn record_heartbeat(&self, details: ActivityHeartbeat) {
589
589
  if let Some(at_mgr) = self.at_task_mgr.as_ref() {
590
- let tt = details.task_token.clone();
590
+ let tt = TaskToken(details.task_token.clone());
591
591
  if let Err(e) = at_mgr.record_heartbeat(details) {
592
- warn!(task_token = ?tt, details = ?e, "Activity heartbeat failed.");
592
+ warn!(task_token = %tt, details = ?e, "Activity heartbeat failed.");
593
593
  }
594
594
  }
595
595
  }
596
596
 
597
597
  #[instrument(skip(self, task_token, status),
598
- fields(task_token=%&task_token, status=%&status,
599
- task_queue=%self.config.task_queue, workflow_id, run_id))]
598
+ fields(task_token=%&task_token, status=%&status,
599
+ task_queue=%self.config.task_queue, workflow_id, run_id))]
600
600
  pub(crate) async fn complete_activity(
601
601
  &self,
602
602
  task_token: TaskToken,
@@ -637,8 +637,8 @@ impl Worker {
637
637
  }
638
638
 
639
639
  #[instrument(skip(self, completion),
640
- fields(completion=%&completion, run_id=%completion.run_id, workflow_id,
641
- task_queue=%self.config.task_queue))]
640
+ fields(completion=%&completion, run_id=%completion.run_id, workflow_id,
641
+ task_queue=%self.config.task_queue))]
642
642
  pub(crate) async fn complete_workflow_activation(
643
643
  &self,
644
644
  completion: WorkflowActivationCompletion,
@@ -53,8 +53,8 @@ impl SlotTrait for Slot {
53
53
  }
54
54
  }
55
55
 
56
- #[derive(derive_more::DebugCustom)]
57
- #[debug(fmt = "SlotProvider {{ namespace:{namespace}, task_queue: {task_queue} }}")]
56
+ #[derive(derive_more::Debug)]
57
+ #[debug("SlotProvider {{ namespace:{namespace}, task_queue: {task_queue} }}")]
58
58
  pub(super) struct SlotProvider {
59
59
  namespace: String,
60
60
  task_queue: String,
@@ -108,6 +108,7 @@ mod tests {
108
108
  // make validate_wft() happy
109
109
  fn new_validatable_response() -> PollWorkflowTaskQueueResponse {
110
110
  PollWorkflowTaskQueueResponse {
111
+ task_token: vec![1, 3, 3, 7],
111
112
  workflow_execution_task_queue: Some(TaskQueue::default()),
112
113
  workflow_execution: Some(WorkflowExecution::default()),
113
114
  workflow_type: Some(WorkflowType::default()),
@@ -130,7 +131,7 @@ mod tests {
130
131
 
131
132
  let slot = provider
132
133
  .try_reserve_wft_slot()
133
- .expect("failed to reserver slot");
134
+ .expect("failed to reserve slot");
134
135
  let p = slot.schedule_wft(new_validatable_response());
135
136
  assert!(p.is_ok());
136
137
  assert!(external_wft_rx.recv().await.is_some());
@@ -440,7 +440,7 @@ impl RealSysInfo {
440
440
  lock.refresh_memory();
441
441
  lock.refresh_cpu_usage();
442
442
  let mem = lock.used_memory();
443
- let cpu = lock.global_cpu_info().cpu_usage() as f64 / 100.;
443
+ let cpu = lock.global_cpu_usage() as f64 / 100.;
444
444
  self.cur_mem_usage.store(mem, Ordering::Release);
445
445
  self.cur_cpu_usage.store(cpu.to_bits(), Ordering::Release);
446
446
  self.last_refresh.store(Instant::now());
@@ -3,10 +3,13 @@ use crate::{
3
3
  worker::workflow::{OutgoingJob, WFCommand, WorkflowStartedInfo},
4
4
  };
5
5
  use prost_types::Timestamp;
6
- use std::sync::mpsc::{self, Receiver, Sender};
6
+ use std::{
7
+ collections::HashMap,
8
+ sync::mpsc::{self, Receiver, Sender},
9
+ };
7
10
  use temporal_sdk_core_protos::{
8
11
  coresdk::workflow_activation::{start_workflow_from_attribs, WorkflowActivationJob},
9
- temporal::api::history::v1::WorkflowExecutionStartedEventAttributes,
12
+ temporal::api::{common::v1::Payload, history::v1::WorkflowExecutionStartedEventAttributes},
10
13
  utilities::TryIntoOrNone,
11
14
  };
12
15
 
@@ -14,6 +17,7 @@ use temporal_sdk_core_protos::{
14
17
  /// command responses pulled out.
15
18
  pub(crate) struct DrivenWorkflow {
16
19
  started_attrs: Option<WorkflowStartedInfo>,
20
+ search_attribute_modifications: HashMap<String, Payload>,
17
21
  incoming_commands: Receiver<Vec<WFCommand>>,
18
22
  /// Outgoing activation jobs that need to be sent to the lang sdk
19
23
  outgoing_wf_activation_jobs: Vec<OutgoingJob>,
@@ -25,6 +29,7 @@ impl DrivenWorkflow {
25
29
  (
26
30
  Self {
27
31
  started_attrs: None,
32
+ search_attribute_modifications: Default::default(),
28
33
  incoming_commands: rx,
29
34
  outgoing_wf_activation_jobs: vec![],
30
35
  },
@@ -85,4 +90,25 @@ impl DrivenWorkflow {
85
90
  debug!(in_cmds = %in_cmds.display(), "wf bridge iteration fetch");
86
91
  in_cmds
87
92
  }
93
+
94
+ /// Lang sent us an SA upsert command - use it to update our current view of search attributes.
95
+ pub(crate) fn search_attributes_update(&mut self, update: HashMap<String, Payload>) {
96
+ self.search_attribute_modifications.extend(update);
97
+ }
98
+
99
+ /// Return a view of the "current" state of search attributes. IE: The initial attributes
100
+ /// plus any changes during the lifetime of the workflow.
101
+ pub(crate) fn get_current_search_attributes(&self) -> HashMap<String, Payload> {
102
+ let mut retme = self
103
+ .started_attrs
104
+ .as_ref()
105
+ .and_then(|si| si.search_attrs.as_ref().map(|sa| sa.indexed_fields.clone()))
106
+ .unwrap_or_default();
107
+ retme.extend(
108
+ self.search_attribute_modifications
109
+ .iter()
110
+ .map(|(a, b)| (a.clone(), b.clone())),
111
+ );
112
+ retme
113
+ }
88
114
  }
@@ -78,8 +78,8 @@ pub(crate) enum NextWFT {
78
78
  NeedFetch,
79
79
  }
80
80
 
81
- #[derive(derive_more::DebugCustom)]
82
- #[debug(fmt = "HistoryPaginator(run_id: {run_id})")]
81
+ #[derive(derive_more::Debug)]
82
+ #[debug("HistoryPaginator(run_id: {run_id})")]
83
83
  pub(crate) struct HistoryPaginator {
84
84
  pub(crate) wf_id: String,
85
85
  pub(crate) run_id: String,