@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.
- package/Cargo.lock +86 -88
- package/lib/index.d.ts +3 -0
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.github/workflows/per-pr.yml +7 -1
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/client/Cargo.toml +3 -3
- package/sdk-core/client/src/lib.rs +1 -1
- package/sdk-core/client/src/metrics.rs +2 -2
- package/sdk-core/client/src/raw.rs +39 -13
- package/sdk-core/client/src/retry.rs +108 -62
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -2
- package/sdk-core/core/Cargo.toml +4 -5
- package/sdk-core/core/src/abstractions.rs +2 -3
- package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +2 -2
- package/sdk-core/core/src/core_tests/queries.rs +8 -4
- package/sdk-core/core/src/core_tests/updates.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +3 -3
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +55 -54
- package/sdk-core/core/src/ephemeral_server/mod.rs +5 -3
- package/sdk-core/core/src/protosext/mod.rs +3 -0
- package/sdk-core/core/src/telemetry/mod.rs +0 -8
- package/sdk-core/core/src/telemetry/otel.rs +7 -3
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +11 -0
- package/sdk-core/core/src/worker/activities.rs +1 -1
- package/sdk-core/core/src/worker/mod.rs +6 -6
- package/sdk-core/core/src/worker/slot_provider.rs +4 -3
- package/sdk-core/core/src/worker/tuner/resource_based.rs +1 -1
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +28 -2
- package/sdk-core/core/src/worker/workflow/history_update.rs +2 -2
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +8 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +7 -7
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +10 -15
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +30 -20
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +2 -2
- package/sdk-core/core/src/worker/workflow/managed_run.rs +20 -4
- package/sdk-core/core/src/worker/workflow/mod.rs +33 -29
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +2 -2
- package/sdk-core/core-api/src/telemetry.rs +1 -0
- package/sdk-core/docker/docker-compose-telem.yaml +4 -4
- package/sdk-core/etc/otel-collector-config.yaml +12 -9
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +2 -2
- package/sdk-core/sdk/src/lib.rs +30 -3
- package/sdk-core/sdk/src/workflow_context.rs +15 -2
- package/sdk-core/sdk/src/workflow_future.rs +28 -8
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +31 -12
- package/sdk-core/sdk-core-protos/src/lib.rs +104 -63
- package/sdk-core/test-utils/src/lib.rs +4 -3
- package/sdk-core/tests/integ_tests/client_tests.rs +36 -7
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/metrics_tests.rs +50 -4
- package/sdk-core/tests/integ_tests/queries_tests.rs +95 -62
- package/sdk-core/tests/integ_tests/update_tests.rs +16 -9
- package/sdk-core/tests/integ_tests/visibility_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/worker_tests.rs +82 -1
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +46 -8
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +81 -2
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +139 -4
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +43 -28
- package/sdk-core/tests/integ_tests/workflow_tests.rs +2 -1
- package/sdk-core/tests/main.rs +28 -19
- package/sdk-core/tests/runner.rs +7 -2
- 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,
|
|
46
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
686
|
-
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
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::
|
|
2446
|
+
variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
2445
2447
|
},
|
|
2446
2448
|
WorkflowActivationJob {
|
|
2447
|
-
variant: Some(workflow_activation_job::Variant::
|
|
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::
|
|
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::
|
|
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
|
|
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::
|
|
571
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
599
|
-
|
|
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
|
-
|
|
641
|
-
|
|
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::
|
|
57
|
-
#[debug(
|
|
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
|
|
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.
|
|
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::
|
|
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::
|
|
82
|
-
#[debug(
|
|
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,
|