@temporalio/core-bridge 1.9.2 → 1.10.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.
- package/Cargo.lock +754 -473
- package/Cargo.toml +3 -3
- package/lib/index.d.ts +33 -2
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
- 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/scripts/build.js +4 -3
- package/sdk-core/.cargo/config.toml +2 -4
- package/sdk-core/.github/workflows/heavy.yml +1 -1
- package/sdk-core/.github/workflows/per-pr.yml +6 -4
- package/sdk-core/Cargo.toml +10 -3
- package/sdk-core/README.md +4 -6
- package/sdk-core/client/Cargo.toml +13 -5
- package/sdk-core/client/src/lib.rs +123 -34
- package/sdk-core/client/src/metrics.rs +70 -18
- package/sdk-core/client/src/proxy.rs +85 -0
- package/sdk-core/client/src/raw.rs +67 -5
- package/sdk-core/client/src/worker_registry/mod.rs +5 -3
- package/sdk-core/client/src/workflow_handle/mod.rs +3 -1
- package/sdk-core/core/Cargo.toml +31 -37
- package/sdk-core/core/src/abstractions/take_cell.rs +3 -3
- package/sdk-core/core/src/abstractions.rs +176 -108
- package/sdk-core/core/src/core_tests/activity_tasks.rs +4 -13
- package/sdk-core/core/src/core_tests/determinism.rs +2 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +3 -3
- package/sdk-core/core/src/core_tests/mod.rs +3 -3
- package/sdk-core/core/src/core_tests/queries.rs +42 -5
- package/sdk-core/core/src/core_tests/workers.rs +2 -3
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +115 -15
- package/sdk-core/core/src/ephemeral_server/mod.rs +109 -136
- package/sdk-core/core/src/internal_flags.rs +8 -8
- package/sdk-core/core/src/lib.rs +16 -11
- package/sdk-core/core/src/pollers/mod.rs +11 -5
- package/sdk-core/core/src/pollers/poll_buffer.rs +48 -29
- package/sdk-core/core/src/protosext/mod.rs +32 -32
- package/sdk-core/core/src/protosext/protocol_messages.rs +14 -24
- package/sdk-core/core/src/retry_logic.rs +2 -2
- package/sdk-core/core/src/telemetry/log_export.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +233 -330
- package/sdk-core/core/src/telemetry/mod.rs +11 -38
- package/sdk-core/core/src/telemetry/otel.rs +355 -0
- package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -23
- package/sdk-core/core/src/test_help/mod.rs +80 -59
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +6 -6
- package/sdk-core/core/src/worker/activities/local_activities.rs +46 -43
- package/sdk-core/core/src/worker/activities.rs +45 -46
- package/sdk-core/core/src/worker/client/mocks.rs +8 -7
- package/sdk-core/core/src/worker/client.rs +40 -39
- package/sdk-core/core/src/worker/mod.rs +72 -42
- package/sdk-core/core/src/worker/slot_provider.rs +28 -28
- package/sdk-core/core/src/worker/slot_supplier.rs +1 -0
- package/sdk-core/core/src/worker/tuner/fixed_size.rs +52 -0
- package/sdk-core/core/src/worker/tuner/resource_based.rs +561 -0
- package/sdk-core/core/src/worker/tuner.rs +122 -0
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +6 -6
- package/sdk-core/core/src/worker/workflow/history_update.rs +27 -53
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +4 -17
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -10
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +4 -11
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +17 -35
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -8
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -14
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -5
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -10
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -10
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +12 -8
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +0 -10
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -13
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +27 -37
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +3 -14
- package/sdk-core/core/src/worker/workflow/managed_run.rs +84 -54
- package/sdk-core/core/src/worker/workflow/mod.rs +63 -160
- package/sdk-core/core/src/worker/workflow/run_cache.rs +22 -13
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +16 -3
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +15 -12
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +39 -78
- package/sdk-core/core-api/Cargo.toml +6 -5
- package/sdk-core/core-api/src/errors.rs +8 -0
- package/sdk-core/core-api/src/telemetry/metrics.rs +75 -4
- package/sdk-core/core-api/src/telemetry.rs +7 -1
- package/sdk-core/core-api/src/worker.rs +212 -56
- package/sdk-core/fsm/Cargo.toml +3 -0
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- package/sdk-core/sdk/Cargo.toml +5 -7
- package/sdk-core/sdk/src/app_data.rs +3 -3
- package/sdk-core/sdk/src/lib.rs +5 -3
- package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
- package/sdk-core/sdk/src/workflow_context.rs +10 -9
- package/sdk-core/sdk/src/workflow_future.rs +1 -1
- package/sdk-core/sdk-core-protos/Cargo.toml +8 -6
- package/sdk-core/sdk-core-protos/build.rs +1 -10
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +3 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/ci.yml +26 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +42 -20
- package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +36 -26
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/struct.proto +95 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +9632 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +7337 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/payload_description.txt +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +45 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +22 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +44 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +18 -3
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +30 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +7 -8
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +23 -5
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +25 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +141 -15
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +12 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +193 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +73 -6
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +46 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +4 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +2 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +116 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +134 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +274 -29
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +57 -1
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +10 -12
- package/sdk-core/sdk-core-protos/src/history_builder.rs +1 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +54 -51
- package/sdk-core/sdk-core-protos/src/task_token.rs +11 -2
- package/sdk-core/test-utils/Cargo.toml +7 -4
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +44 -62
- package/sdk-core/tests/fuzzy_workflow.rs +5 -2
- package/sdk-core/tests/heavy_tests.rs +114 -17
- package/sdk-core/tests/integ_tests/activity_functions.rs +1 -1
- package/sdk-core/tests/integ_tests/client_tests.rs +2 -2
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +38 -26
- package/sdk-core/tests/integ_tests/metrics_tests.rs +126 -17
- package/sdk-core/tests/integ_tests/polling_tests.rs +118 -2
- package/sdk-core/tests/integ_tests/update_tests.rs +3 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -4
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -2
- package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +6 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +9 -7
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +14 -9
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +6 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +9 -6
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +5 -5
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests.rs +115 -11
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +57 -0
- package/src/lib.rs +1 -0
- package/src/runtime.rs +51 -35
- package/ts/index.ts +67 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
- package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
- package/sdk-core/sdk/src/payload_converter.rs +0 -11
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +0 -2
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/docker-compose.yml +0 -15
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/pipeline.yml +0 -10
- package/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
- package/sdk-core/tests/wf_input_replay.rs +0 -32
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//! This module contains very generic helpers that can be used codebase-wide
|
|
2
2
|
|
|
3
|
-
pub mod take_cell;
|
|
3
|
+
pub(crate) mod take_cell;
|
|
4
4
|
|
|
5
5
|
use crate::MetricsContext;
|
|
6
6
|
use derive_more::DebugCustom;
|
|
@@ -11,102 +11,149 @@ use std::{
|
|
|
11
11
|
Arc,
|
|
12
12
|
},
|
|
13
13
|
};
|
|
14
|
-
use
|
|
14
|
+
use temporal_sdk_core_api::worker::{
|
|
15
|
+
SlotKind, SlotReservationContext, SlotSupplier, SlotSupplierPermit,
|
|
16
|
+
};
|
|
17
|
+
use tokio::sync::watch;
|
|
15
18
|
use tokio_util::sync::CancellationToken;
|
|
16
19
|
|
|
17
|
-
/// Wraps a [
|
|
18
|
-
///
|
|
20
|
+
/// Wraps a [SlotSupplier] and turns successful slot reservations into permit structs, as well
|
|
21
|
+
/// as handling associated metrics tracking.
|
|
19
22
|
#[derive(Clone)]
|
|
20
|
-
pub(crate) struct
|
|
21
|
-
|
|
22
|
-
/// The number of permit owners who have acquired a permit
|
|
23
|
-
///
|
|
24
|
-
///
|
|
25
|
-
///
|
|
23
|
+
pub(crate) struct MeteredPermitDealer<SK: SlotKind> {
|
|
24
|
+
supplier: Arc<dyn SlotSupplier<SlotKind = SK> + Send + Sync>,
|
|
25
|
+
/// The number of permit owners who have acquired a permit, but are not yet meaningfully using
|
|
26
|
+
/// that permit. This is useful for giving a more semantically accurate count of used task
|
|
27
|
+
/// slots, since we typically wait for a permit first before polling, but that slot isn't used
|
|
28
|
+
/// in the sense the user expects until we actually also get the corresponding task.
|
|
26
29
|
unused_claimants: Arc<AtomicUsize>,
|
|
30
|
+
/// The number of permits that have been handed out
|
|
31
|
+
extant_permits: (watch::Sender<usize>, watch::Receiver<usize>),
|
|
32
|
+
/// The maximum number of extant permits which are allowed. Once the number of extant permits
|
|
33
|
+
/// is at this number, no more permits will be requested from the supplier until one is freed.
|
|
34
|
+
/// This avoids requesting slots when we are at the workflow cache size limit. If and when
|
|
35
|
+
/// we add user-defined cache sizing, that logic will need to live with the supplier and
|
|
36
|
+
/// there will need to be some associated refactoring.
|
|
37
|
+
max_permits: Option<usize>,
|
|
27
38
|
metrics_ctx: MetricsContext,
|
|
28
|
-
record_fn: fn(&MetricsContext, usize),
|
|
29
39
|
}
|
|
30
40
|
|
|
31
|
-
impl
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
impl<SK> MeteredPermitDealer<SK>
|
|
42
|
+
where
|
|
43
|
+
SK: SlotKind + 'static,
|
|
44
|
+
{
|
|
45
|
+
pub(crate) fn new(
|
|
46
|
+
supplier: Arc<dyn SlotSupplier<SlotKind = SK> + Send + Sync>,
|
|
34
47
|
metrics_ctx: MetricsContext,
|
|
35
|
-
|
|
48
|
+
max_permits: Option<usize>,
|
|
36
49
|
) -> Self {
|
|
37
50
|
Self {
|
|
38
|
-
|
|
51
|
+
supplier,
|
|
39
52
|
unused_claimants: Arc::new(AtomicUsize::new(0)),
|
|
53
|
+
extant_permits: watch::channel(0),
|
|
40
54
|
metrics_ctx,
|
|
41
|
-
|
|
55
|
+
max_permits,
|
|
42
56
|
}
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
pub fn available_permits(&self) -> usize {
|
|
46
|
-
self.
|
|
59
|
+
pub(crate) fn available_permits(&self) -> Option<usize> {
|
|
60
|
+
self.supplier.available_slots()
|
|
47
61
|
}
|
|
48
62
|
|
|
49
63
|
#[cfg(test)]
|
|
50
|
-
pub fn unused_permits(&self) -> usize {
|
|
51
|
-
self.
|
|
64
|
+
pub(crate) fn unused_permits(&self) -> Option<usize> {
|
|
65
|
+
self.available_permits()
|
|
66
|
+
.map(|ap| ap + self.unused_claimants.load(Ordering::Acquire))
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
pub async fn acquire_owned(&self) -> Result<OwnedMeteredSemPermit
|
|
55
|
-
let
|
|
69
|
+
pub(crate) async fn acquire_owned(&self) -> Result<OwnedMeteredSemPermit<SK>, ()> {
|
|
70
|
+
if let Some(max) = self.max_permits {
|
|
71
|
+
self.extant_permits
|
|
72
|
+
.1
|
|
73
|
+
.clone()
|
|
74
|
+
.wait_for(|&ep| ep < max)
|
|
75
|
+
.await
|
|
76
|
+
.expect("Extant permit channel is never closed");
|
|
77
|
+
}
|
|
78
|
+
let res = self.supplier.reserve_slot(self).await;
|
|
56
79
|
Ok(self.build_owned(res))
|
|
57
80
|
}
|
|
58
81
|
|
|
59
|
-
pub fn try_acquire_owned(&self) -> Result<OwnedMeteredSemPermit
|
|
60
|
-
let
|
|
61
|
-
|
|
82
|
+
pub(crate) fn try_acquire_owned(&self) -> Result<OwnedMeteredSemPermit<SK>, ()> {
|
|
83
|
+
if let Some(max) = self.max_permits {
|
|
84
|
+
if *self.extant_permits.1.borrow() >= max {
|
|
85
|
+
return Err(());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if let Some(res) = self.supplier.try_reserve_slot(self) {
|
|
89
|
+
Ok(self.build_owned(res))
|
|
90
|
+
} else {
|
|
91
|
+
Err(())
|
|
92
|
+
}
|
|
62
93
|
}
|
|
63
94
|
|
|
64
|
-
fn build_owned(&self, res:
|
|
95
|
+
fn build_owned(&self, res: SlotSupplierPermit) -> OwnedMeteredSemPermit<SK> {
|
|
65
96
|
self.unused_claimants.fetch_add(1, Ordering::Release);
|
|
66
|
-
self.
|
|
97
|
+
self.extant_permits.0.send_modify(|ep| *ep += 1);
|
|
98
|
+
// Eww
|
|
99
|
+
let uc_c = self.unused_claimants.clone();
|
|
100
|
+
let ep_rx_c = self.extant_permits.1.clone();
|
|
101
|
+
let ep_tx_c = self.extant_permits.0.clone();
|
|
102
|
+
let supp = self.supplier.clone();
|
|
103
|
+
let supp_c = self.supplier.clone();
|
|
104
|
+
let supp_c_c = self.supplier.clone();
|
|
105
|
+
let mets = self.metrics_ctx.clone();
|
|
106
|
+
let metric_rec =
|
|
107
|
+
// When being called from the drop impl, the permit isn't actually dropped yet, so
|
|
108
|
+
// account for that with the `add_one` parameter.
|
|
109
|
+
move |add_one: bool| {
|
|
110
|
+
let extra = usize::from(add_one);
|
|
111
|
+
let unused = uc_c.load(Ordering::Acquire);
|
|
112
|
+
if let Some(avail) = supp.available_slots() {
|
|
113
|
+
mets.available_task_slots(avail + unused + extra);
|
|
114
|
+
}
|
|
115
|
+
mets.task_slots_used((ep_rx_c.borrow().saturating_sub(unused) + extra) as u64);
|
|
116
|
+
};
|
|
117
|
+
let mrc = metric_rec.clone();
|
|
118
|
+
mrc(false);
|
|
119
|
+
|
|
67
120
|
OwnedMeteredSemPermit {
|
|
68
|
-
|
|
121
|
+
_inner: res,
|
|
69
122
|
unused_claimants: Some(self.unused_claimants.clone()),
|
|
70
|
-
|
|
123
|
+
use_fn: Box::new(move |info| {
|
|
124
|
+
supp_c.mark_slot_used(info);
|
|
125
|
+
metric_rec(false)
|
|
126
|
+
}),
|
|
127
|
+
release_fn: Box::new(move || {
|
|
128
|
+
supp_c_c.release_slot();
|
|
129
|
+
ep_tx_c.send_modify(|ep| *ep -= 1);
|
|
130
|
+
mrc(true)
|
|
131
|
+
}),
|
|
71
132
|
}
|
|
72
133
|
}
|
|
134
|
+
}
|
|
73
135
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.sem.available_permits() + self.unused_claimants.load(Ordering::Acquire),
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
fn record_owned(&self) -> Box<dyn Fn(bool) + Send + Sync> {
|
|
82
|
-
let rcf = self.record_fn;
|
|
83
|
-
let mets = self.metrics_ctx.clone();
|
|
84
|
-
let sem = self.sem.clone();
|
|
85
|
-
let uc = self.unused_claimants.clone();
|
|
86
|
-
// When being called from the drop impl, the semaphore permit isn't actually dropped yet,
|
|
87
|
-
// so account for that.
|
|
88
|
-
Box::new(move |add_one: bool| {
|
|
89
|
-
let extra = usize::from(add_one);
|
|
90
|
-
rcf(
|
|
91
|
-
&mets,
|
|
92
|
-
sem.available_permits() + uc.load(Ordering::Acquire) + extra,
|
|
93
|
-
)
|
|
94
|
-
})
|
|
136
|
+
impl<SK: SlotKind> SlotReservationContext for MeteredPermitDealer<SK> {
|
|
137
|
+
fn num_issued_slots(&self) -> usize {
|
|
138
|
+
*self.extant_permits.1.borrow()
|
|
95
139
|
}
|
|
96
140
|
}
|
|
97
141
|
|
|
98
|
-
/// A version of [
|
|
142
|
+
/// A version of [MeteredPermitDealer] that can be closed and supports waiting for close to complete.
|
|
99
143
|
/// Once closed, no permits will be handed out.
|
|
100
144
|
/// Close completes when all permits have been returned.
|
|
101
|
-
pub(crate) struct
|
|
102
|
-
inner: Arc<
|
|
145
|
+
pub(crate) struct ClosableMeteredPermitDealer<SK: SlotKind> {
|
|
146
|
+
inner: Arc<MeteredPermitDealer<SK>>,
|
|
103
147
|
outstanding_permits: AtomicUsize,
|
|
104
148
|
close_requested: AtomicBool,
|
|
105
149
|
close_complete_token: CancellationToken,
|
|
106
150
|
}
|
|
107
151
|
|
|
108
|
-
impl
|
|
109
|
-
|
|
152
|
+
impl<SK> ClosableMeteredPermitDealer<SK>
|
|
153
|
+
where
|
|
154
|
+
SK: SlotKind,
|
|
155
|
+
{
|
|
156
|
+
pub(crate) fn new_arc(sem: Arc<MeteredPermitDealer<SK>>) -> Arc<Self> {
|
|
110
157
|
Arc::new(Self {
|
|
111
158
|
inner: sem,
|
|
112
159
|
outstanding_permits: Default::default(),
|
|
@@ -116,14 +163,17 @@ impl ClosableMeteredSemaphore {
|
|
|
116
163
|
}
|
|
117
164
|
}
|
|
118
165
|
|
|
119
|
-
impl
|
|
166
|
+
impl<SK> ClosableMeteredPermitDealer<SK>
|
|
167
|
+
where
|
|
168
|
+
SK: SlotKind + 'static,
|
|
169
|
+
{
|
|
120
170
|
#[cfg(test)]
|
|
121
|
-
pub fn unused_permits(&self) -> usize {
|
|
171
|
+
pub(crate) fn unused_permits(&self) -> Option<usize> {
|
|
122
172
|
self.inner.unused_permits()
|
|
123
173
|
}
|
|
124
174
|
|
|
125
175
|
/// Request to close the semaphore and prevent new permits from being acquired.
|
|
126
|
-
pub fn close(&self) {
|
|
176
|
+
pub(crate) fn close(&self) {
|
|
127
177
|
self.close_requested.store(true, Ordering::Release);
|
|
128
178
|
if self.outstanding_permits.load(Ordering::Acquire) == 0 {
|
|
129
179
|
self.close_complete_token.cancel();
|
|
@@ -131,16 +181,16 @@ impl ClosableMeteredSemaphore {
|
|
|
131
181
|
}
|
|
132
182
|
|
|
133
183
|
/// Returns after close has been requested and all outstanding permits have been returned.
|
|
134
|
-
pub async fn close_complete(&self) {
|
|
184
|
+
pub(crate) async fn close_complete(&self) {
|
|
135
185
|
self.close_complete_token.cancelled().await;
|
|
136
186
|
}
|
|
137
187
|
|
|
138
188
|
/// Acquire a permit if one is available and close was not requested.
|
|
139
|
-
pub fn try_acquire_owned(
|
|
189
|
+
pub(crate) fn try_acquire_owned(
|
|
140
190
|
self: &Arc<Self>,
|
|
141
|
-
) -> Result<TrackedOwnedMeteredSemPermit
|
|
191
|
+
) -> Result<TrackedOwnedMeteredSemPermit<SK>, ()> {
|
|
142
192
|
if self.close_requested.load(Ordering::Acquire) {
|
|
143
|
-
return Err(
|
|
193
|
+
return Err(());
|
|
144
194
|
}
|
|
145
195
|
self.outstanding_permits.fetch_add(1, Ordering::Release);
|
|
146
196
|
let res = self.inner.try_acquire_owned();
|
|
@@ -168,72 +218,64 @@ impl ClosableMeteredSemaphore {
|
|
|
168
218
|
|
|
169
219
|
/// Tracks an OwnedMeteredSemPermit and calls on_drop when dropped.
|
|
170
220
|
#[derive(DebugCustom)]
|
|
221
|
+
#[clippy::has_significant_drop]
|
|
171
222
|
#[debug(fmt = "Tracked({inner:?})")]
|
|
172
|
-
pub(crate) struct TrackedOwnedMeteredSemPermit {
|
|
173
|
-
inner: Option<OwnedMeteredSemPermit
|
|
223
|
+
pub(crate) struct TrackedOwnedMeteredSemPermit<SK: SlotKind> {
|
|
224
|
+
inner: Option<OwnedMeteredSemPermit<SK>>,
|
|
174
225
|
on_drop: Box<dyn Fn() + Send + Sync>,
|
|
175
226
|
}
|
|
176
|
-
impl From<TrackedOwnedMeteredSemPermit
|
|
177
|
-
fn from(mut value: TrackedOwnedMeteredSemPermit) -> Self {
|
|
227
|
+
impl<SK: SlotKind> From<TrackedOwnedMeteredSemPermit<SK>> for OwnedMeteredSemPermit<SK> {
|
|
228
|
+
fn from(mut value: TrackedOwnedMeteredSemPermit<SK>) -> Self {
|
|
178
229
|
value
|
|
179
230
|
.inner
|
|
180
231
|
.take()
|
|
181
232
|
.expect("Inner permit should be available")
|
|
182
233
|
}
|
|
183
234
|
}
|
|
184
|
-
impl Drop for TrackedOwnedMeteredSemPermit {
|
|
235
|
+
impl<SK: SlotKind> Drop for TrackedOwnedMeteredSemPermit<SK> {
|
|
185
236
|
fn drop(&mut self) {
|
|
186
237
|
(self.on_drop)();
|
|
187
238
|
}
|
|
188
239
|
}
|
|
189
240
|
|
|
190
|
-
/// Wraps an [
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
241
|
+
/// Wraps an [SlotSupplierPermit] to update metrics & when it's dropped
|
|
242
|
+
#[clippy::has_significant_drop]
|
|
243
|
+
pub(crate) struct OwnedMeteredSemPermit<SK: SlotKind> {
|
|
244
|
+
_inner: SlotSupplierPermit,
|
|
245
|
+
/// See [MeteredPermitDealer::unused_claimants]. If present when dropping, used to decrement the
|
|
194
246
|
/// count.
|
|
195
247
|
unused_claimants: Option<Arc<AtomicUsize>>,
|
|
196
|
-
|
|
248
|
+
#[allow(clippy::type_complexity)] // not really tho, bud
|
|
249
|
+
use_fn: Box<dyn Fn(SK::Info<'_>) + Send + Sync>,
|
|
250
|
+
release_fn: Box<dyn Fn() + Send + Sync>,
|
|
197
251
|
}
|
|
198
|
-
impl Drop for OwnedMeteredSemPermit {
|
|
252
|
+
impl<SK: SlotKind> Drop for OwnedMeteredSemPermit<SK> {
|
|
199
253
|
fn drop(&mut self) {
|
|
200
254
|
if let Some(uc) = self.unused_claimants.take() {
|
|
201
255
|
uc.fetch_sub(1, Ordering::Release);
|
|
202
256
|
}
|
|
203
|
-
(self.
|
|
257
|
+
(self.release_fn)()
|
|
204
258
|
}
|
|
205
259
|
}
|
|
206
|
-
impl Debug for OwnedMeteredSemPermit {
|
|
260
|
+
impl<SK: SlotKind> Debug for OwnedMeteredSemPermit<SK> {
|
|
207
261
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
208
|
-
|
|
262
|
+
f.write_str("OwnedMeteredSemPermit()")
|
|
209
263
|
}
|
|
210
264
|
}
|
|
211
|
-
impl OwnedMeteredSemPermit {
|
|
265
|
+
impl<SK: SlotKind> OwnedMeteredSemPermit<SK> {
|
|
212
266
|
/// Should be called once this permit is actually being "used" for the work it was meant to
|
|
213
267
|
/// permit.
|
|
214
|
-
pub(crate) fn into_used(mut self) -> UsedMeteredSemPermit {
|
|
268
|
+
pub(crate) fn into_used(mut self, info: SK::Info<'_>) -> UsedMeteredSemPermit<SK> {
|
|
215
269
|
if let Some(uc) = self.unused_claimants.take() {
|
|
216
270
|
uc.fetch_sub(1, Ordering::Release);
|
|
217
|
-
(self.record_fn)(false)
|
|
218
271
|
}
|
|
272
|
+
(self.use_fn)(info);
|
|
219
273
|
UsedMeteredSemPermit(self)
|
|
220
274
|
}
|
|
221
275
|
}
|
|
222
276
|
|
|
223
277
|
#[derive(Debug)]
|
|
224
|
-
pub(crate) struct UsedMeteredSemPermit(OwnedMeteredSemPermit);
|
|
225
|
-
impl UsedMeteredSemPermit {
|
|
226
|
-
#[cfg(feature = "save_wf_inputs")]
|
|
227
|
-
pub(crate) fn fake_deserialized() -> Self {
|
|
228
|
-
let sem = Arc::new(Semaphore::new(1));
|
|
229
|
-
let inner = sem.try_acquire_owned().unwrap();
|
|
230
|
-
Self(OwnedMeteredSemPermit {
|
|
231
|
-
inner,
|
|
232
|
-
unused_claimants: None,
|
|
233
|
-
record_fn: Box::new(|_| {}),
|
|
234
|
-
})
|
|
235
|
-
}
|
|
236
|
-
}
|
|
278
|
+
pub(crate) struct UsedMeteredSemPermit<SK: SlotKind>(#[allow(dead_code)] OwnedMeteredSemPermit<SK>);
|
|
237
279
|
|
|
238
280
|
macro_rules! dbg_panic {
|
|
239
281
|
($($arg:tt)*) => {
|
|
@@ -244,13 +286,26 @@ macro_rules! dbg_panic {
|
|
|
244
286
|
pub(crate) use dbg_panic;
|
|
245
287
|
|
|
246
288
|
#[cfg(test)]
|
|
247
|
-
mod tests {
|
|
289
|
+
pub(crate) mod tests {
|
|
248
290
|
use super::*;
|
|
291
|
+
use crate::{advance_fut, worker::tuner::FixedSizeSlotSupplier};
|
|
292
|
+
use futures_util::FutureExt;
|
|
293
|
+
use temporal_sdk_core_api::worker::WorkflowSlotKind;
|
|
249
294
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
295
|
+
pub(crate) fn fixed_size_permit_dealer<SK: SlotKind + Send + Sync + 'static>(
|
|
296
|
+
size: usize,
|
|
297
|
+
) -> MeteredPermitDealer<SK> {
|
|
298
|
+
MeteredPermitDealer::new(
|
|
299
|
+
Arc::new(FixedSizeSlotSupplier::new(size)),
|
|
300
|
+
MetricsContext::no_op(),
|
|
301
|
+
None,
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
#[test]
|
|
306
|
+
fn closable_semaphore_permit_drop_returns_permit() {
|
|
307
|
+
let inner = fixed_size_permit_dealer::<WorkflowSlotKind>(2);
|
|
308
|
+
let sem = ClosableMeteredPermitDealer::new_arc(Arc::new(inner));
|
|
254
309
|
let perm = sem.try_acquire_owned().unwrap();
|
|
255
310
|
let permits = sem.outstanding_permits.load(Ordering::Acquire);
|
|
256
311
|
assert_eq!(permits, 1);
|
|
@@ -261,8 +316,8 @@ mod tests {
|
|
|
261
316
|
|
|
262
317
|
#[tokio::test]
|
|
263
318
|
async fn closable_semaphore_permit_drop_after_close_resolves_close_complete() {
|
|
264
|
-
let inner =
|
|
265
|
-
let sem =
|
|
319
|
+
let inner = fixed_size_permit_dealer::<WorkflowSlotKind>(2);
|
|
320
|
+
let sem = ClosableMeteredPermitDealer::new_arc(Arc::new(inner));
|
|
266
321
|
let perm = sem.try_acquire_owned().unwrap();
|
|
267
322
|
sem.close();
|
|
268
323
|
drop(perm);
|
|
@@ -271,18 +326,31 @@ mod tests {
|
|
|
271
326
|
|
|
272
327
|
#[tokio::test]
|
|
273
328
|
async fn closable_semaphore_close_complete_ready_if_unused() {
|
|
274
|
-
let inner =
|
|
275
|
-
let sem =
|
|
329
|
+
let inner = fixed_size_permit_dealer::<WorkflowSlotKind>(2);
|
|
330
|
+
let sem = ClosableMeteredPermitDealer::new_arc(Arc::new(inner));
|
|
276
331
|
sem.close();
|
|
277
332
|
sem.close_complete().await;
|
|
278
333
|
}
|
|
279
334
|
|
|
280
|
-
#[
|
|
281
|
-
|
|
282
|
-
let inner =
|
|
283
|
-
let sem =
|
|
335
|
+
#[test]
|
|
336
|
+
fn closable_semaphore_does_not_hand_out_permits_after_closed() {
|
|
337
|
+
let inner = fixed_size_permit_dealer::<WorkflowSlotKind>(2);
|
|
338
|
+
let sem = ClosableMeteredPermitDealer::new_arc(Arc::new(inner));
|
|
284
339
|
sem.close();
|
|
285
|
-
|
|
286
|
-
|
|
340
|
+
sem.try_acquire_owned().unwrap_err();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
#[tokio::test]
|
|
344
|
+
async fn respects_max_extant_permits() {
|
|
345
|
+
let mut sem = fixed_size_permit_dealer::<WorkflowSlotKind>(2);
|
|
346
|
+
sem.max_permits = Some(1);
|
|
347
|
+
let perm = sem.try_acquire_owned().unwrap();
|
|
348
|
+
sem.try_acquire_owned().unwrap_err();
|
|
349
|
+
let acquire_fut = sem.acquire_owned();
|
|
350
|
+
// Will be pending
|
|
351
|
+
advance_fut!(acquire_fut);
|
|
352
|
+
drop(perm);
|
|
353
|
+
// Now it'll proceed
|
|
354
|
+
acquire_fut.await.unwrap();
|
|
287
355
|
}
|
|
288
356
|
}
|
|
@@ -7,7 +7,7 @@ use crate::{
|
|
|
7
7
|
QueueResponse, ResponseType, WorkerExt, WorkflowCachingPolicy, TEST_Q,
|
|
8
8
|
},
|
|
9
9
|
worker::client::mocks::{mock_manual_workflow_client, mock_workflow_client},
|
|
10
|
-
ActivityHeartbeat, Worker,
|
|
10
|
+
ActivityHeartbeat, Worker,
|
|
11
11
|
};
|
|
12
12
|
use futures::FutureExt;
|
|
13
13
|
use itertools::Itertools;
|
|
@@ -618,11 +618,8 @@ async fn max_tq_acts_set_passed_to_poll_properly() {
|
|
|
618
618
|
})
|
|
619
619
|
});
|
|
620
620
|
|
|
621
|
-
let cfg =
|
|
622
|
-
.namespace("enchi")
|
|
623
|
-
.task_queue("cat")
|
|
621
|
+
let cfg = test_worker_cfg()
|
|
624
622
|
.max_concurrent_at_polls(1_usize)
|
|
625
|
-
.worker_build_id("test_bin_id")
|
|
626
623
|
.max_task_queue_activities_per_second(rate)
|
|
627
624
|
.build()
|
|
628
625
|
.unwrap();
|
|
@@ -921,7 +918,7 @@ async fn activity_tasks_from_completion_reserve_slots() {
|
|
|
921
918
|
let mut mock = build_mock_pollers(mh);
|
|
922
919
|
mock.worker_cfg(|cfg| {
|
|
923
920
|
cfg.max_cached_workflows = 2;
|
|
924
|
-
cfg.max_outstanding_activities = 2;
|
|
921
|
+
cfg.max_outstanding_activities = Some(2);
|
|
925
922
|
});
|
|
926
923
|
mock.set_act_poller(mock_poller_from_resps(act_tasks));
|
|
927
924
|
let core = Arc::new(mock_worker(mock));
|
|
@@ -1030,13 +1027,7 @@ async fn cant_complete_activity_with_unset_result_payload() {
|
|
|
1030
1027
|
})
|
|
1031
1028
|
});
|
|
1032
1029
|
|
|
1033
|
-
let
|
|
1034
|
-
.namespace("enchi")
|
|
1035
|
-
.task_queue("cat")
|
|
1036
|
-
.worker_build_id("enchi_loves_salmon")
|
|
1037
|
-
.build()
|
|
1038
|
-
.unwrap();
|
|
1039
|
-
let worker = Worker::new_test(cfg, mock_client);
|
|
1030
|
+
let worker = Worker::new_test(test_worker_cfg().build().unwrap(), mock_client);
|
|
1040
1031
|
let t = worker.poll_activity_task().await.unwrap();
|
|
1041
1032
|
let res = worker
|
|
1042
1033
|
.complete_activity_task(ActivityTaskCompletion {
|
|
@@ -21,7 +21,8 @@ use temporal_sdk_core_protos::{
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
static DID_FAIL: AtomicBool = AtomicBool::new(false);
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
pub(crate) async fn timer_wf_fails_once(ctx: WfContext) -> WorkflowResult<()> {
|
|
25
26
|
ctx.timer(Duration::from_secs(1)).await;
|
|
26
27
|
if DID_FAIL
|
|
27
28
|
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
|
|
@@ -112,7 +112,7 @@ async fn local_act_two_wfts_before_marker(#[case] replay: bool, #[case] cached:
|
|
|
112
112
|
worker.run_until_done().await.unwrap();
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
pub async fn local_act_fanout_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
115
|
+
pub(crate) async fn local_act_fanout_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
116
116
|
let las: Vec<_> = (1..=50)
|
|
117
117
|
.map(|i| {
|
|
118
118
|
ctx.local_activity(LocalActivityOptions {
|
|
@@ -187,7 +187,7 @@ async fn local_act_heartbeat(#[case] shutdown_middle: bool) {
|
|
|
187
187
|
mh.enforce_correct_number_of_polls = false;
|
|
188
188
|
let mut worker = mock_sdk_cfg(mh, |wc| {
|
|
189
189
|
wc.max_cached_workflows = 1;
|
|
190
|
-
wc.max_outstanding_workflow_tasks = 1;
|
|
190
|
+
wc.max_outstanding_workflow_tasks = Some(1);
|
|
191
191
|
});
|
|
192
192
|
let core = worker.core_worker.clone();
|
|
193
193
|
|
|
@@ -1084,7 +1084,7 @@ async fn local_act_records_nonfirst_attempts_ok() {
|
|
|
1084
1084
|
}));
|
|
1085
1085
|
let mut worker = mock_sdk_cfg(mh, |wc| {
|
|
1086
1086
|
wc.max_cached_workflows = 1;
|
|
1087
|
-
wc.max_outstanding_workflow_tasks = 1;
|
|
1087
|
+
wc.max_outstanding_workflow_tasks = Some(1);
|
|
1088
1088
|
});
|
|
1089
1089
|
|
|
1090
1090
|
worker.register_wf(
|
|
@@ -16,6 +16,7 @@ use crate::{
|
|
|
16
16
|
Worker,
|
|
17
17
|
};
|
|
18
18
|
use futures::FutureExt;
|
|
19
|
+
use once_cell::sync::Lazy;
|
|
19
20
|
use std::time::Duration;
|
|
20
21
|
use temporal_sdk_core_api::Worker as WorkerTrait;
|
|
21
22
|
use temporal_sdk_core_protos::coresdk::workflow_completion::WorkflowActivationCompletion;
|
|
@@ -45,9 +46,8 @@ async fn after_shutdown_server_is_not_polled() {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
// Better than cloning a billion arcs...
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
49
|
+
static BARR: Lazy<Barrier> = Lazy::new(|| Barrier::new(3));
|
|
50
|
+
|
|
51
51
|
#[tokio::test]
|
|
52
52
|
async fn shutdown_interrupts_both_polls() {
|
|
53
53
|
let mut mock_client = mock_manual_workflow_client();
|
|
@@ -893,8 +893,9 @@ async fn build_id_set_properly_on_query_on_first_task() {
|
|
|
893
893
|
core.drain_pollers_and_shutdown().await;
|
|
894
894
|
}
|
|
895
895
|
|
|
896
|
+
#[rstest::rstest]
|
|
896
897
|
#[tokio::test]
|
|
897
|
-
async fn queries_arent_lost_in_buffer_void() {
|
|
898
|
+
async fn queries_arent_lost_in_buffer_void(#[values(false, true)] buffered_because_cache: bool) {
|
|
898
899
|
let wfid = "fake_wf_id";
|
|
899
900
|
let mut t = TestHistoryBuilder::default();
|
|
900
901
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
@@ -902,7 +903,24 @@ async fn queries_arent_lost_in_buffer_void() {
|
|
|
902
903
|
t.add_we_signaled("sig", vec![]);
|
|
903
904
|
t.add_full_wf_task();
|
|
904
905
|
t.add_workflow_execution_completed();
|
|
905
|
-
|
|
906
|
+
|
|
907
|
+
let mut tasks = if buffered_because_cache {
|
|
908
|
+
// A history for another wf which will occupy the only cache slot initially
|
|
909
|
+
let mut t1 = TestHistoryBuilder::default();
|
|
910
|
+
t1.add_by_type(EventType::WorkflowExecutionStarted);
|
|
911
|
+
t1.add_full_wf_task();
|
|
912
|
+
t1.add_workflow_execution_completed();
|
|
913
|
+
|
|
914
|
+
vec![hist_to_poll_resp(
|
|
915
|
+
&t1,
|
|
916
|
+
"cache_occupier".to_owned(),
|
|
917
|
+
1.into(),
|
|
918
|
+
)]
|
|
919
|
+
} else {
|
|
920
|
+
vec![]
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
tasks.extend([
|
|
906
924
|
hist_to_poll_resp(&t, wfid.to_owned(), 1.into()),
|
|
907
925
|
{
|
|
908
926
|
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
|
|
@@ -923,8 +941,7 @@ async fn queries_arent_lost_in_buffer_void() {
|
|
|
923
941
|
pr
|
|
924
942
|
},
|
|
925
943
|
hist_to_poll_resp(&t, wfid.to_owned(), 2.into()),
|
|
926
|
-
]
|
|
927
|
-
.map(|r| r.resp);
|
|
944
|
+
]);
|
|
928
945
|
|
|
929
946
|
let mut mock = mock_workflow_client();
|
|
930
947
|
mock.expect_complete_workflow_task()
|
|
@@ -932,10 +949,30 @@ async fn queries_arent_lost_in_buffer_void() {
|
|
|
932
949
|
mock.expect_respond_legacy_query()
|
|
933
950
|
.times(2)
|
|
934
951
|
.returning(|_, _| Ok(Default::default()));
|
|
935
|
-
let mut mock =
|
|
952
|
+
let mut mock =
|
|
953
|
+
MocksHolder::from_wft_stream(mock, stream::iter(tasks.into_iter().map(|r| r.resp)));
|
|
936
954
|
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
937
955
|
let core = mock_worker(mock);
|
|
938
956
|
|
|
957
|
+
if buffered_because_cache {
|
|
958
|
+
// Poll for and complete the occupying workflow
|
|
959
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
960
|
+
core.complete_execution(&task.run_id).await;
|
|
961
|
+
// Get the cache removal task
|
|
962
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
963
|
+
assert_matches!(
|
|
964
|
+
task.jobs.as_slice(),
|
|
965
|
+
[WorkflowActivationJob {
|
|
966
|
+
variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
|
|
967
|
+
}]
|
|
968
|
+
);
|
|
969
|
+
// Wait a beat to ensure the other task(s) have a chance to be buffered
|
|
970
|
+
tokio::time::sleep(Duration::from_millis(100)).await;
|
|
971
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
|
|
972
|
+
.await
|
|
973
|
+
.unwrap();
|
|
974
|
+
}
|
|
975
|
+
|
|
939
976
|
let task = core.poll_workflow_activation().await.unwrap();
|
|
940
977
|
core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
|
|
941
978
|
.await
|
|
@@ -175,7 +175,7 @@ async fn complete_with_task_not_found_during_shutdown() {
|
|
|
175
175
|
// Initiate shutdown before completing the activation
|
|
176
176
|
let shutdown_fut = async {
|
|
177
177
|
core.shutdown().await;
|
|
178
|
-
complete_order.borrow_mut().push(
|
|
178
|
+
complete_order.borrow_mut().push(2);
|
|
179
179
|
};
|
|
180
180
|
let poll_fut = async {
|
|
181
181
|
// This will return shutdown once the completion goes through
|
|
@@ -183,7 +183,6 @@ async fn complete_with_task_not_found_during_shutdown() {
|
|
|
183
183
|
core.poll_workflow_activation().await.unwrap_err(),
|
|
184
184
|
PollWfError::ShutDown
|
|
185
185
|
);
|
|
186
|
-
complete_order.borrow_mut().push(2);
|
|
187
186
|
};
|
|
188
187
|
let complete_fut = async {
|
|
189
188
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
@@ -195,7 +194,7 @@ async fn complete_with_task_not_found_during_shutdown() {
|
|
|
195
194
|
complete_order.borrow_mut().push(1);
|
|
196
195
|
};
|
|
197
196
|
tokio::join!(shutdown_fut, poll_fut, complete_fut);
|
|
198
|
-
assert_eq!(&complete_order.into_inner(), &[1, 2
|
|
197
|
+
assert_eq!(&complete_order.into_inner(), &[1, 2])
|
|
199
198
|
}
|
|
200
199
|
|
|
201
200
|
#[tokio::test]
|