@temporalio/core-bridge 1.7.1 → 1.7.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 +21 -0
- 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/client/src/raw.rs +15 -6
- package/sdk-core/core/Cargo.toml +1 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +13 -5
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +21 -39
- package/sdk-core/core/src/internal_flags.rs +132 -46
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +10 -7
- package/sdk-core/core/src/worker/activities.rs +152 -142
- package/sdk-core/core/src/worker/client.rs +12 -8
- package/sdk-core/core/src/worker/mod.rs +7 -5
- package/sdk-core/core/src/worker/workflow/history_update.rs +86 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +4 -1
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +5 -2
- package/sdk-core/core/src/worker/workflow/managed_run.rs +0 -1
- package/sdk-core/protos/api_upstream/.github/workflows/publish-docs.yml +23 -0
- package/sdk-core/protos/api_upstream/Makefile +1 -1
- package/sdk-core/protos/api_upstream/buf.yaml +5 -0
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +17 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +6 -3
- package/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +12 -22
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +145 -48
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +19 -8
- package/sdk-core/test-utils/src/lib.rs +29 -7
- package/sdk-core/tests/integ_tests/activity_functions.rs +5 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +5 -7
- package/sdk-core/tests/integ_tests/workflow_tests.rs +3 -7
- package/sdk-core/tests/main.rs +1 -0
package/Cargo.lock
CHANGED
|
@@ -517,6 +517,26 @@ dependencies = [
|
|
|
517
517
|
"cfg-if",
|
|
518
518
|
]
|
|
519
519
|
|
|
520
|
+
[[package]]
|
|
521
|
+
name = "enum-iterator"
|
|
522
|
+
version = "1.4.0"
|
|
523
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
524
|
+
checksum = "706d9e7cf1c7664859d79cd524e4e53ea2b67ea03c98cc2870c5e539695d597e"
|
|
525
|
+
dependencies = [
|
|
526
|
+
"enum-iterator-derive",
|
|
527
|
+
]
|
|
528
|
+
|
|
529
|
+
[[package]]
|
|
530
|
+
name = "enum-iterator-derive"
|
|
531
|
+
version = "1.2.0"
|
|
532
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
533
|
+
checksum = "355f93763ef7b0ae1c43c4d8eccc9d5848d84ad1a1d8ce61c421d1ac85a19d05"
|
|
534
|
+
dependencies = [
|
|
535
|
+
"proc-macro2",
|
|
536
|
+
"quote",
|
|
537
|
+
"syn 1.0.109",
|
|
538
|
+
]
|
|
539
|
+
|
|
520
540
|
[[package]]
|
|
521
541
|
name = "enum_dispatch"
|
|
522
542
|
version = "0.3.11"
|
|
@@ -2272,6 +2292,7 @@ dependencies = [
|
|
|
2272
2292
|
"dashmap",
|
|
2273
2293
|
"derive_builder",
|
|
2274
2294
|
"derive_more",
|
|
2295
|
+
"enum-iterator",
|
|
2275
2296
|
"enum_dispatch",
|
|
2276
2297
|
"flate2",
|
|
2277
2298
|
"futures",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@temporalio/core-bridge",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Temporal.io SDK Core<>Node bridge",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@opentelemetry/api": "^1.3.0",
|
|
26
|
-
"@temporalio/common": "1.7.
|
|
26
|
+
"@temporalio/common": "1.7.2",
|
|
27
27
|
"arg": "^5.0.2",
|
|
28
28
|
"cargo-cp-artifact": "^0.1.6",
|
|
29
29
|
"which": "^2.0.2"
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "779561124eecdec8396e658c0a1305d343dfaff7"
|
|
57
57
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -740,9 +740,9 @@ proxier! {
|
|
|
740
740
|
}
|
|
741
741
|
);
|
|
742
742
|
(
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
743
|
+
update_worker_build_id_compatibility,
|
|
744
|
+
UpdateWorkerBuildIdCompatibilityRequest,
|
|
745
|
+
UpdateWorkerBuildIdCompatibilityResponse,
|
|
746
746
|
|r| {
|
|
747
747
|
let mut labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
|
|
748
748
|
labels.task_q_str(r.get_ref().task_queue.clone());
|
|
@@ -750,9 +750,9 @@ proxier! {
|
|
|
750
750
|
}
|
|
751
751
|
);
|
|
752
752
|
(
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
753
|
+
get_worker_build_id_compatibility,
|
|
754
|
+
GetWorkerBuildIdCompatibilityRequest,
|
|
755
|
+
GetWorkerBuildIdCompatibilityResponse,
|
|
756
756
|
|r| {
|
|
757
757
|
let mut labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
|
|
758
758
|
labels.task_q_str(r.get_ref().task_queue.clone());
|
|
@@ -768,6 +768,15 @@ proxier! {
|
|
|
768
768
|
r.extensions_mut().insert(labels);
|
|
769
769
|
}
|
|
770
770
|
);
|
|
771
|
+
(
|
|
772
|
+
poll_workflow_execution_update,
|
|
773
|
+
PollWorkflowExecutionUpdateRequest,
|
|
774
|
+
PollWorkflowExecutionUpdateResponse,
|
|
775
|
+
|r| {
|
|
776
|
+
let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
|
|
777
|
+
r.extensions_mut().insert(labels);
|
|
778
|
+
}
|
|
779
|
+
);
|
|
771
780
|
(
|
|
772
781
|
start_batch_operation,
|
|
773
782
|
StartBatchOperationRequest,
|
package/sdk-core/core/Cargo.toml
CHANGED
|
@@ -58,7 +58,7 @@ use temporal_sdk_core_protos::{
|
|
|
58
58
|
TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE,
|
|
59
59
|
};
|
|
60
60
|
use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd, TestWorker};
|
|
61
|
-
use tokio::{sync::Barrier, time::sleep};
|
|
61
|
+
use tokio::{join, sync::Barrier, time::sleep};
|
|
62
62
|
use tokio_util::sync::CancellationToken;
|
|
63
63
|
|
|
64
64
|
fn three_tasks() -> VecDeque<PollActivityTaskQueueResponse> {
|
|
@@ -288,7 +288,7 @@ async fn activity_cancel_interrupts_poll() {
|
|
|
288
288
|
// Perform first poll to get the activity registered
|
|
289
289
|
let act = core.poll_activity_task().await.unwrap();
|
|
290
290
|
// Poll should block until heartbeat is sent, issuing the cancel, and interrupting the poll
|
|
291
|
-
|
|
291
|
+
join! {
|
|
292
292
|
async {
|
|
293
293
|
core.record_activity_heartbeat(ActivityHeartbeat {
|
|
294
294
|
task_token: act.task_token,
|
|
@@ -984,7 +984,7 @@ async fn activity_tasks_from_completion_reserve_slots() {
|
|
|
984
984
|
// This wf poll should *not* set the flag that it wants tasks back since both slots are
|
|
985
985
|
// occupied
|
|
986
986
|
let run_fut = async { worker.run_until_done().await.unwrap() };
|
|
987
|
-
|
|
987
|
+
join!(run_fut, act_completer);
|
|
988
988
|
}
|
|
989
989
|
|
|
990
990
|
#[tokio::test]
|
|
@@ -1052,9 +1052,11 @@ async fn cant_complete_activity_with_unset_result_payload() {
|
|
|
1052
1052
|
)
|
|
1053
1053
|
}
|
|
1054
1054
|
|
|
1055
|
+
#[rstest::rstest]
|
|
1055
1056
|
#[tokio::test]
|
|
1056
|
-
async fn graceful_shutdown() {
|
|
1057
|
+
async fn graceful_shutdown(#[values(true, false)] at_max_outstanding: bool) {
|
|
1057
1058
|
let _task_q = "q";
|
|
1059
|
+
let grace_period = Duration::from_millis(200);
|
|
1058
1060
|
let mut tasks = three_tasks();
|
|
1059
1061
|
let mut mock_client = mock_workflow_client();
|
|
1060
1062
|
mock_client
|
|
@@ -1067,15 +1069,21 @@ async fn graceful_shutdown() {
|
|
|
1067
1069
|
.times(3)
|
|
1068
1070
|
.returning(|_, _| Ok(Default::default()));
|
|
1069
1071
|
|
|
1072
|
+
let max_outstanding = if at_max_outstanding { 3_usize } else { 100 };
|
|
1070
1073
|
let worker = Worker::new_test(
|
|
1071
1074
|
test_worker_cfg()
|
|
1072
|
-
.graceful_shutdown_period(
|
|
1075
|
+
.graceful_shutdown_period(grace_period)
|
|
1076
|
+
.max_outstanding_activities(max_outstanding)
|
|
1073
1077
|
.build()
|
|
1074
1078
|
.unwrap(),
|
|
1075
1079
|
mock_client,
|
|
1076
1080
|
);
|
|
1077
1081
|
|
|
1078
1082
|
let _1 = worker.poll_activity_task().await.unwrap();
|
|
1083
|
+
|
|
1084
|
+
// Wait at least the grace period after one poll - ensuring it doesn't trigger prematurely
|
|
1085
|
+
tokio::time::sleep(grace_period.mul_f32(1.1)).await;
|
|
1086
|
+
|
|
1079
1087
|
let _2 = worker.poll_activity_task().await.unwrap();
|
|
1080
1088
|
let _3 = worker.poll_activity_task().await.unwrap();
|
|
1081
1089
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
advance_fut,
|
|
2
|
+
advance_fut,
|
|
3
|
+
internal_flags::CoreInternalFlags,
|
|
4
|
+
job_assert,
|
|
3
5
|
replay::TestHistoryBuilder,
|
|
4
6
|
test_help::{
|
|
5
7
|
build_fake_worker, build_mock_pollers, build_multihist_mock_sg, canned_histories,
|
|
@@ -14,9 +16,9 @@ use crate::{
|
|
|
14
16
|
use futures::{stream, FutureExt};
|
|
15
17
|
use rstest::{fixture, rstest};
|
|
16
18
|
use std::{
|
|
17
|
-
collections::{HashMap, VecDeque},
|
|
19
|
+
collections::{HashMap, HashSet, VecDeque},
|
|
18
20
|
sync::{
|
|
19
|
-
atomic::{
|
|
21
|
+
atomic::{AtomicU64, Ordering},
|
|
20
22
|
Arc,
|
|
21
23
|
},
|
|
22
24
|
time::Duration,
|
|
@@ -54,9 +56,7 @@ use temporal_sdk_core_protos::{
|
|
|
54
56
|
},
|
|
55
57
|
DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE,
|
|
56
58
|
};
|
|
57
|
-
use temporal_sdk_core_test_utils::{
|
|
58
|
-
fanout_tasks, schedule_activity_cmd, start_timer_cmd, WorkerTestHelpers,
|
|
59
|
-
};
|
|
59
|
+
use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd, WorkerTestHelpers};
|
|
60
60
|
use tokio::{
|
|
61
61
|
join,
|
|
62
62
|
sync::{Barrier, Semaphore},
|
|
@@ -2297,7 +2297,7 @@ async fn ensure_fetching_fail_during_complete_sends_task_failure() {
|
|
|
2297
2297
|
mock.expect_get_workflow_execution_history()
|
|
2298
2298
|
.returning(move |_, _, _| {
|
|
2299
2299
|
error!("Called fetch second time!");
|
|
2300
|
-
|
|
2300
|
+
Err(tonic::Status::not_found("Ahh broken"))
|
|
2301
2301
|
})
|
|
2302
2302
|
.times(1);
|
|
2303
2303
|
mock.expect_fail_workflow_task()
|
|
@@ -2380,54 +2380,36 @@ async fn lang_internal_flags() {
|
|
|
2380
2380
|
core.shutdown().await;
|
|
2381
2381
|
}
|
|
2382
2382
|
|
|
2383
|
-
// Verify we send flags
|
|
2383
|
+
// Verify we send all core internal flags on the first non-replay WFT
|
|
2384
2384
|
#[tokio::test]
|
|
2385
2385
|
async fn core_internal_flags() {
|
|
2386
2386
|
let mut t = TestHistoryBuilder::default();
|
|
2387
2387
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
2388
|
-
t.
|
|
2389
|
-
let act_scheduled_event_id = t.add_activity_task_scheduled("act-id");
|
|
2390
|
-
let act_started_event_id = t.add_activity_task_started(act_scheduled_event_id);
|
|
2391
|
-
t.add_activity_task_completed(
|
|
2392
|
-
act_scheduled_event_id,
|
|
2393
|
-
act_started_event_id,
|
|
2394
|
-
Default::default(),
|
|
2395
|
-
);
|
|
2396
|
-
t.add_full_wf_task();
|
|
2397
|
-
t.add_workflow_execution_completed();
|
|
2388
|
+
t.add_workflow_task_scheduled_and_started();
|
|
2398
2389
|
|
|
2399
2390
|
let mut mh = MockPollCfg::from_resp_batches(
|
|
2400
2391
|
"fake_wf_id",
|
|
2401
2392
|
t,
|
|
2402
|
-
[ResponseType::ToTaskNum(1)
|
|
2393
|
+
[ResponseType::ToTaskNum(1)],
|
|
2403
2394
|
mock_workflow_client(),
|
|
2404
2395
|
);
|
|
2405
|
-
let first_poll = AtomicBool::new(true);
|
|
2406
2396
|
mh.completion_asserts = Some(Box::new(move |c| {
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2397
|
+
assert_eq!(
|
|
2398
|
+
c.sdk_metadata
|
|
2399
|
+
.core_used_flags
|
|
2400
|
+
.iter()
|
|
2401
|
+
.copied()
|
|
2402
|
+
.collect::<HashSet<_>>(),
|
|
2403
|
+
CoreInternalFlags::all_except_too_high()
|
|
2404
|
+
.into_iter()
|
|
2405
|
+
.map(|f| f as u32)
|
|
2406
|
+
.collect()
|
|
2407
|
+
);
|
|
2411
2408
|
}));
|
|
2412
2409
|
let mut mock = build_mock_pollers(mh);
|
|
2413
2410
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
2414
2411
|
let core = mock_worker(mock);
|
|
2415
2412
|
|
|
2416
|
-
let act = core.poll_workflow_activation().await.unwrap();
|
|
2417
|
-
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
2418
|
-
act.run_id,
|
|
2419
|
-
schedule_activity_cmd(
|
|
2420
|
-
1,
|
|
2421
|
-
"whatever",
|
|
2422
|
-
"act-id",
|
|
2423
|
-
ActivityCancellationType::TryCancel,
|
|
2424
|
-
Duration::from_secs(60),
|
|
2425
|
-
Duration::from_secs(60),
|
|
2426
|
-
),
|
|
2427
|
-
))
|
|
2428
|
-
.await
|
|
2429
|
-
.unwrap();
|
|
2430
|
-
|
|
2431
2413
|
let act = core.poll_workflow_activation().await.unwrap();
|
|
2432
2414
|
core.complete_execution(&act.run_id).await;
|
|
2433
2415
|
core.shutdown().await;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
//! Utilities for and tracking of internal versions which alter history in incompatible ways
|
|
2
2
|
//! so that we can use older code paths for workflows executed on older core versions.
|
|
3
3
|
|
|
4
|
-
use
|
|
4
|
+
use itertools::Either;
|
|
5
|
+
use std::{
|
|
6
|
+
collections::{BTreeSet, HashSet},
|
|
7
|
+
iter,
|
|
8
|
+
};
|
|
5
9
|
use temporal_sdk_core_protos::temporal::api::{
|
|
6
10
|
history::v1::WorkflowTaskCompletedEventAttributes, sdk::v1::WorkflowTaskCompletedMetadata,
|
|
7
11
|
workflowservice::v1::get_system_info_response,
|
|
@@ -15,7 +19,7 @@ use temporal_sdk_core_protos::temporal::api::{
|
|
|
15
19
|
/// that removing older variants does not create any change in existing values. Removed flag
|
|
16
20
|
/// variants must be reserved forever (a-la protobuf), and should be called out in a comment.
|
|
17
21
|
#[repr(u32)]
|
|
18
|
-
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)]
|
|
22
|
+
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug, enum_iterator::Sequence)]
|
|
19
23
|
pub(crate) enum CoreInternalFlags {
|
|
20
24
|
/// In this flag additional checks were added to a number of state machines to ensure that
|
|
21
25
|
/// the ID and type of activities, local activities, and child workflows match during replay.
|
|
@@ -28,64 +32,85 @@ pub(crate) enum CoreInternalFlags {
|
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
31
|
-
pub(crate)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
pub(crate) enum InternalFlags {
|
|
36
|
+
Enabled {
|
|
37
|
+
core: BTreeSet<CoreInternalFlags>,
|
|
38
|
+
lang: BTreeSet<u32>,
|
|
39
|
+
core_since_last_complete: HashSet<CoreInternalFlags>,
|
|
40
|
+
lang_since_last_complete: HashSet<u32>,
|
|
41
|
+
},
|
|
42
|
+
Disabled,
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
impl InternalFlags {
|
|
40
46
|
pub fn new(server_capabilities: &get_system_info_response::Capabilities) -> Self {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
match server_capabilities.sdk_metadata {
|
|
48
|
+
true => Self::Enabled {
|
|
49
|
+
core: Default::default(),
|
|
50
|
+
lang: Default::default(),
|
|
51
|
+
core_since_last_complete: Default::default(),
|
|
52
|
+
lang_since_last_complete: Default::default(),
|
|
53
|
+
},
|
|
54
|
+
false => Self::Disabled,
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
pub fn add_from_complete(&mut self, e: &WorkflowTaskCompletedEventAttributes) {
|
|
51
|
-
if
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
);
|
|
62
|
-
self.lang.extend(metadata.lang_used_flags.iter());
|
|
59
|
+
if let Self::Enabled { core, lang, .. } = self {
|
|
60
|
+
if let Some(metadata) = e.sdk_metadata.as_ref() {
|
|
61
|
+
core.extend(
|
|
62
|
+
metadata
|
|
63
|
+
.core_used_flags
|
|
64
|
+
.iter()
|
|
65
|
+
.map(|u| CoreInternalFlags::from_u32(*u)),
|
|
66
|
+
);
|
|
67
|
+
lang.extend(metadata.lang_used_flags.iter());
|
|
68
|
+
}
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
pub fn add_lang_used(&mut self, flags: impl IntoIterator<Item = u32>) {
|
|
67
|
-
if
|
|
68
|
-
|
|
73
|
+
if let Self::Enabled {
|
|
74
|
+
lang_since_last_complete,
|
|
75
|
+
..
|
|
76
|
+
} = self
|
|
77
|
+
{
|
|
78
|
+
lang_since_last_complete.extend(flags.into_iter());
|
|
69
79
|
}
|
|
70
|
-
|
|
71
|
-
self.lang_since_last_complete.extend(flags.into_iter());
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
/// Returns true if this flag may currently be used. If `should_record` is true, always returns
|
|
75
83
|
/// true and records the flag as being used, for taking later via
|
|
76
84
|
/// [Self::gather_for_wft_complete].
|
|
77
85
|
pub fn try_use(&mut self, core_patch: CoreInternalFlags, should_record: bool) -> bool {
|
|
78
|
-
|
|
86
|
+
match self {
|
|
87
|
+
Self::Enabled {
|
|
88
|
+
core,
|
|
89
|
+
core_since_last_complete,
|
|
90
|
+
..
|
|
91
|
+
} => {
|
|
92
|
+
if should_record {
|
|
93
|
+
core_since_last_complete.insert(core_patch);
|
|
94
|
+
true
|
|
95
|
+
} else {
|
|
96
|
+
core.contains(&core_patch)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
79
99
|
// If the server does not support the metadata field, we must assume we can never use
|
|
80
100
|
// any internal flags since they can't be recorded for future use
|
|
81
|
-
|
|
101
|
+
Self::Disabled => false,
|
|
82
102
|
}
|
|
103
|
+
}
|
|
83
104
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
105
|
+
/// Writes all known core flags to the set which should be recorded in the current WFT if not
|
|
106
|
+
/// already known. Must only be called if not replaying.
|
|
107
|
+
pub fn write_all_known(&mut self) {
|
|
108
|
+
if let Self::Enabled {
|
|
109
|
+
core_since_last_complete,
|
|
110
|
+
..
|
|
111
|
+
} = self
|
|
112
|
+
{
|
|
113
|
+
core_since_last_complete.extend(CoreInternalFlags::all_except_too_high());
|
|
89
114
|
}
|
|
90
115
|
}
|
|
91
116
|
|
|
@@ -93,18 +118,39 @@ impl InternalFlags {
|
|
|
93
118
|
/// sdk metadata message that can be combined with any existing data before sending the WFT
|
|
94
119
|
/// complete
|
|
95
120
|
pub fn gather_for_wft_complete(&mut self) -> WorkflowTaskCompletedMetadata {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
121
|
+
match self {
|
|
122
|
+
Self::Enabled {
|
|
123
|
+
core_since_last_complete,
|
|
124
|
+
lang_since_last_complete,
|
|
125
|
+
core,
|
|
126
|
+
lang,
|
|
127
|
+
} => {
|
|
128
|
+
let core_newly_used: Vec<_> = core_since_last_complete
|
|
129
|
+
.iter()
|
|
130
|
+
.filter(|f| !core.contains(f))
|
|
131
|
+
.map(|p| *p as u32)
|
|
132
|
+
.collect();
|
|
133
|
+
let lang_newly_used: Vec<_> = lang_since_last_complete
|
|
134
|
+
.iter()
|
|
135
|
+
.filter(|f| !lang.contains(f))
|
|
136
|
+
.copied()
|
|
137
|
+
.collect();
|
|
138
|
+
core.extend(core_since_last_complete.iter());
|
|
139
|
+
lang.extend(lang_since_last_complete.iter());
|
|
140
|
+
WorkflowTaskCompletedMetadata {
|
|
141
|
+
core_used_flags: core_newly_used,
|
|
142
|
+
lang_used_flags: lang_newly_used,
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
Self::Disabled => WorkflowTaskCompletedMetadata::default(),
|
|
103
146
|
}
|
|
104
147
|
}
|
|
105
148
|
|
|
106
|
-
pub fn all_lang(&self) ->
|
|
107
|
-
|
|
149
|
+
pub fn all_lang(&self) -> impl Iterator<Item = u32> + '_ {
|
|
150
|
+
match self {
|
|
151
|
+
Self::Enabled { lang, .. } => Either::Left(lang.iter().copied()),
|
|
152
|
+
Self::Disabled => Either::Right(iter::empty()),
|
|
153
|
+
}
|
|
108
154
|
}
|
|
109
155
|
}
|
|
110
156
|
|
|
@@ -116,6 +162,11 @@ impl CoreInternalFlags {
|
|
|
116
162
|
_ => Self::TooHigh,
|
|
117
163
|
}
|
|
118
164
|
}
|
|
165
|
+
|
|
166
|
+
pub fn all_except_too_high() -> impl Iterator<Item = CoreInternalFlags> {
|
|
167
|
+
enum_iterator::all::<CoreInternalFlags>()
|
|
168
|
+
.filter(|f| !matches!(f, CoreInternalFlags::TooHigh))
|
|
169
|
+
}
|
|
119
170
|
}
|
|
120
171
|
|
|
121
172
|
#[cfg(test)]
|
|
@@ -138,4 +189,39 @@ mod tests {
|
|
|
138
189
|
assert_matches!(gathered.core_used_flags.as_slice(), &[]);
|
|
139
190
|
assert_matches!(gathered.lang_used_flags.as_slice(), &[]);
|
|
140
191
|
}
|
|
192
|
+
|
|
193
|
+
#[test]
|
|
194
|
+
fn all_have_u32_from_impl() {
|
|
195
|
+
let all_known = CoreInternalFlags::all_except_too_high();
|
|
196
|
+
for flag in all_known {
|
|
197
|
+
let as_u32 = flag as u32;
|
|
198
|
+
assert_eq!(CoreInternalFlags::from_u32(as_u32), flag);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#[test]
|
|
203
|
+
fn only_writes_new_flags() {
|
|
204
|
+
let mut f = InternalFlags::new(&Capabilities {
|
|
205
|
+
sdk_metadata: true,
|
|
206
|
+
..Default::default()
|
|
207
|
+
});
|
|
208
|
+
f.add_lang_used([1]);
|
|
209
|
+
f.try_use(CoreInternalFlags::IdAndTypeDeterminismChecks, true);
|
|
210
|
+
let gathered = f.gather_for_wft_complete();
|
|
211
|
+
assert_matches!(gathered.core_used_flags.as_slice(), &[1]);
|
|
212
|
+
assert_matches!(gathered.lang_used_flags.as_slice(), &[1]);
|
|
213
|
+
|
|
214
|
+
f.add_from_complete(&WorkflowTaskCompletedEventAttributes {
|
|
215
|
+
sdk_metadata: Some(WorkflowTaskCompletedMetadata {
|
|
216
|
+
core_used_flags: vec![2],
|
|
217
|
+
lang_used_flags: vec![2],
|
|
218
|
+
}),
|
|
219
|
+
..Default::default()
|
|
220
|
+
});
|
|
221
|
+
f.add_lang_used([2]);
|
|
222
|
+
f.try_use(CoreInternalFlags::UpsertSearchAttributeOnPatch, true);
|
|
223
|
+
let gathered = f.gather_for_wft_complete();
|
|
224
|
+
assert_matches!(gathered.core_used_flags.as_slice(), &[]);
|
|
225
|
+
assert_matches!(gathered.lang_used_flags.as_slice(), &[]);
|
|
226
|
+
}
|
|
141
227
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
use crate::
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
use crate::{
|
|
2
|
+
abstractions::MeteredSemaphore, pollers::BoxedActPoller, worker::activities::PermittedTqResp,
|
|
3
|
+
MetricsContext,
|
|
4
|
+
};
|
|
4
5
|
use futures::{stream, Stream};
|
|
5
|
-
use governor::
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
use governor::{
|
|
7
|
+
clock::DefaultClock,
|
|
8
|
+
middleware::NoOpMiddleware,
|
|
9
|
+
state::{InMemoryState, NotKeyed},
|
|
10
|
+
RateLimiter,
|
|
11
|
+
};
|
|
9
12
|
use std::sync::Arc;
|
|
10
13
|
use temporal_sdk_core_protos::temporal::api::workflowservice::v1::PollActivityTaskQueueResponse;
|
|
11
14
|
use tokio::select;
|