@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
|
@@ -37,7 +37,7 @@ use temporal_sdk_core_api::{
|
|
|
37
37
|
};
|
|
38
38
|
use temporal_sdk_core_protos::{
|
|
39
39
|
coresdk::{
|
|
40
|
-
workflow_activation::WorkflowActivation,
|
|
40
|
+
workflow_activation::{workflow_activation_job, WorkflowActivation},
|
|
41
41
|
workflow_commands::workflow_command,
|
|
42
42
|
workflow_completion::{self, workflow_activation_completion, WorkflowActivationCompletion},
|
|
43
43
|
},
|
|
@@ -51,15 +51,15 @@ use temporal_sdk_core_protos::{
|
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
|
-
use temporal_sdk_core_test_utils::TestWorker;
|
|
54
|
+
use temporal_sdk_core_test_utils::{TestWorker, NAMESPACE};
|
|
55
55
|
use tokio::sync::{mpsc::unbounded_channel, Notify};
|
|
56
56
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
|
57
57
|
|
|
58
|
-
pub const TEST_Q: &str = "q";
|
|
58
|
+
pub(crate) const TEST_Q: &str = "q";
|
|
59
59
|
|
|
60
|
-
pub fn test_worker_cfg() -> WorkerConfigBuilder {
|
|
60
|
+
pub(crate) fn test_worker_cfg() -> WorkerConfigBuilder {
|
|
61
61
|
let mut wcb = WorkerConfigBuilder::default();
|
|
62
|
-
wcb.namespace(
|
|
62
|
+
wcb.namespace(NAMESPACE)
|
|
63
63
|
.task_queue(TEST_Q)
|
|
64
64
|
.worker_build_id("test_bin_id")
|
|
65
65
|
.ignore_evicts_on_shutdown(true)
|
|
@@ -71,7 +71,7 @@ pub fn test_worker_cfg() -> WorkerConfigBuilder {
|
|
|
71
71
|
/// When constructing responses for mocks, indicates how a given response should be built
|
|
72
72
|
#[derive(derive_more::From)]
|
|
73
73
|
#[allow(clippy::large_enum_variant)] // Test only code, whatever.
|
|
74
|
-
pub enum ResponseType {
|
|
74
|
+
pub(crate) enum ResponseType {
|
|
75
75
|
ToTaskNum(usize),
|
|
76
76
|
/// Returns just the history after the WFT completed of the provided task number - 1, through to
|
|
77
77
|
/// the next WFT started. Simulating the incremental history for just the provided task number
|
|
@@ -84,8 +84,9 @@ pub enum ResponseType {
|
|
|
84
84
|
AllHistory,
|
|
85
85
|
Raw(PollWorkflowTaskQueueResponse),
|
|
86
86
|
}
|
|
87
|
+
|
|
87
88
|
#[derive(Eq, PartialEq, Hash)]
|
|
88
|
-
pub enum HashableResponseType {
|
|
89
|
+
pub(crate) enum HashableResponseType {
|
|
89
90
|
ToTaskNum(usize),
|
|
90
91
|
OneTask(usize),
|
|
91
92
|
UntilResolved(usize),
|
|
@@ -93,8 +94,9 @@ pub enum HashableResponseType {
|
|
|
93
94
|
AllHistory,
|
|
94
95
|
Raw(TaskToken),
|
|
95
96
|
}
|
|
97
|
+
|
|
96
98
|
impl ResponseType {
|
|
97
|
-
|
|
99
|
+
fn hashable(&self) -> HashableResponseType {
|
|
98
100
|
match self {
|
|
99
101
|
ResponseType::ToTaskNum(x) => HashableResponseType::ToTaskNum(*x),
|
|
100
102
|
ResponseType::OneTask(x) => HashableResponseType::OneTask(*x),
|
|
@@ -107,6 +109,7 @@ impl ResponseType {
|
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
111
|
}
|
|
112
|
+
|
|
110
113
|
impl From<&usize> for ResponseType {
|
|
111
114
|
fn from(u: &usize) -> Self {
|
|
112
115
|
Self::ToTaskNum(*u)
|
|
@@ -139,7 +142,10 @@ pub(crate) fn build_fake_worker(
|
|
|
139
142
|
|
|
140
143
|
pub(crate) fn build_fake_sdk(mock_cfg: MockPollCfg) -> temporal_sdk::Worker {
|
|
141
144
|
let mut mock = build_mock_pollers(mock_cfg);
|
|
142
|
-
mock.worker_cfg(|c|
|
|
145
|
+
mock.worker_cfg(|c| {
|
|
146
|
+
c.max_cached_workflows = 1;
|
|
147
|
+
c.ignore_evicts_on_shutdown = false;
|
|
148
|
+
});
|
|
143
149
|
let core = mock_worker(mock);
|
|
144
150
|
let mut worker = temporal_sdk::Worker::new_from_core(Arc::new(core), "replay_q".to_string());
|
|
145
151
|
worker.set_worker_interceptor(FailOnNondeterminismInterceptor {});
|
|
@@ -179,37 +185,39 @@ pub(crate) fn mock_sdk_cfg(
|
|
|
179
185
|
TestWorker::new(Arc::new(core), TEST_Q.to_string())
|
|
180
186
|
}
|
|
181
187
|
|
|
182
|
-
pub struct FakeWfResponses {
|
|
183
|
-
pub wf_id: String,
|
|
184
|
-
pub hist: TestHistoryBuilder,
|
|
185
|
-
pub response_batches: Vec<ResponseType>,
|
|
188
|
+
pub(crate) struct FakeWfResponses {
|
|
189
|
+
pub(crate) wf_id: String,
|
|
190
|
+
pub(crate) hist: TestHistoryBuilder,
|
|
191
|
+
pub(crate) response_batches: Vec<ResponseType>,
|
|
186
192
|
}
|
|
187
193
|
|
|
188
194
|
// TODO: Should be all-internal to this module
|
|
189
|
-
pub struct MocksHolder {
|
|
195
|
+
pub(crate) struct MocksHolder {
|
|
190
196
|
client: Arc<dyn WorkerClient>,
|
|
191
197
|
inputs: MockWorkerInputs,
|
|
192
|
-
pub outstanding_task_map: Option<OutstandingWFTMap>,
|
|
198
|
+
pub(crate) outstanding_task_map: Option<OutstandingWFTMap>,
|
|
193
199
|
}
|
|
194
200
|
|
|
195
201
|
impl MocksHolder {
|
|
196
|
-
pub fn worker_cfg(&mut self, mutator: impl FnOnce(&mut WorkerConfig)) {
|
|
202
|
+
pub(crate) fn worker_cfg(&mut self, mutator: impl FnOnce(&mut WorkerConfig)) {
|
|
197
203
|
mutator(&mut self.inputs.config);
|
|
198
204
|
}
|
|
199
|
-
|
|
205
|
+
|
|
206
|
+
pub(crate) fn set_act_poller(&mut self, poller: BoxedPoller<PollActivityTaskQueueResponse>) {
|
|
200
207
|
self.inputs.act_poller = Some(poller);
|
|
201
208
|
}
|
|
209
|
+
|
|
202
210
|
/// Can be used for tests that need to avoid auto-shutdown due to running out of mock responses
|
|
203
|
-
pub fn make_wft_stream_interminable(&mut self) {
|
|
211
|
+
pub(crate) fn make_wft_stream_interminable(&mut self) {
|
|
204
212
|
let old_stream = std::mem::replace(&mut self.inputs.wft_stream, stream::pending().boxed());
|
|
205
213
|
self.inputs.wft_stream = old_stream.chain(stream::pending()).boxed();
|
|
206
214
|
}
|
|
207
215
|
}
|
|
208
216
|
|
|
209
|
-
pub struct MockWorkerInputs {
|
|
210
|
-
pub wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
|
|
211
|
-
pub act_poller: Option<BoxedPoller<PollActivityTaskQueueResponse>>,
|
|
212
|
-
pub config: WorkerConfig,
|
|
217
|
+
pub(crate) struct MockWorkerInputs {
|
|
218
|
+
pub(crate) wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
|
|
219
|
+
pub(crate) act_poller: Option<BoxedPoller<PollActivityTaskQueueResponse>>,
|
|
220
|
+
pub(crate) config: WorkerConfig,
|
|
213
221
|
}
|
|
214
222
|
|
|
215
223
|
impl Default for MockWorkerInputs {
|
|
@@ -219,7 +227,7 @@ impl Default for MockWorkerInputs {
|
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
impl MockWorkerInputs {
|
|
222
|
-
pub fn new(
|
|
230
|
+
pub(crate) fn new(
|
|
223
231
|
wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
|
|
224
232
|
) -> Self {
|
|
225
233
|
Self {
|
|
@@ -313,7 +321,7 @@ where
|
|
|
313
321
|
Box::new(mock_poller) as BoxedPoller<T>
|
|
314
322
|
}
|
|
315
323
|
|
|
316
|
-
pub fn mock_poller<T>() -> MockPoller<T>
|
|
324
|
+
pub(crate) fn mock_poller<T>() -> MockPoller<T>
|
|
317
325
|
where
|
|
318
326
|
T: Send + Sync + 'static,
|
|
319
327
|
{
|
|
@@ -323,7 +331,7 @@ where
|
|
|
323
331
|
mock_poller
|
|
324
332
|
}
|
|
325
333
|
|
|
326
|
-
pub fn mock_manual_poller<T>() -> MockManualPoller<T>
|
|
334
|
+
pub(crate) fn mock_manual_poller<T>() -> MockManualPoller<T>
|
|
327
335
|
where
|
|
328
336
|
T: Send + Sync + 'static,
|
|
329
337
|
{
|
|
@@ -372,25 +380,25 @@ pub(crate) fn single_hist_mock_sg(
|
|
|
372
380
|
|
|
373
381
|
#[allow(clippy::type_complexity)]
|
|
374
382
|
pub(crate) struct MockPollCfg {
|
|
375
|
-
pub hists: Vec<FakeWfResponses>,
|
|
376
|
-
pub enforce_correct_number_of_polls: bool,
|
|
377
|
-
pub num_expected_fails: usize,
|
|
378
|
-
pub num_expected_legacy_query_resps: usize,
|
|
379
|
-
pub mock_client: MockWorkerClient,
|
|
383
|
+
pub(crate) hists: Vec<FakeWfResponses>,
|
|
384
|
+
pub(crate) enforce_correct_number_of_polls: bool,
|
|
385
|
+
pub(crate) num_expected_fails: usize,
|
|
386
|
+
pub(crate) num_expected_legacy_query_resps: usize,
|
|
387
|
+
pub(crate) mock_client: MockWorkerClient,
|
|
380
388
|
/// All calls to fail WFTs must match this predicate
|
|
381
|
-
pub expect_fail_wft_matcher:
|
|
389
|
+
pub(crate) expect_fail_wft_matcher:
|
|
382
390
|
Box<dyn Fn(&TaskToken, &WorkflowTaskFailedCause, &Option<Failure>) -> bool + Send>,
|
|
383
|
-
pub completion_asserts: Option<Box<dyn FnMut(&WorkflowTaskCompletion) + Send>>,
|
|
384
|
-
pub num_expected_completions: Option<TimesRange>,
|
|
391
|
+
pub(crate) completion_asserts: Option<Box<dyn FnMut(&WorkflowTaskCompletion) + Send>>,
|
|
392
|
+
pub(crate) num_expected_completions: Option<TimesRange>,
|
|
385
393
|
/// If being used with the Rust SDK, this is set true. It ensures pollers will not error out
|
|
386
394
|
/// early with no work, since we cannot know the exact number of times polling will happen.
|
|
387
395
|
/// Instead, they will just block forever.
|
|
388
|
-
pub using_rust_sdk: bool,
|
|
389
|
-
pub make_poll_stream_interminable: bool,
|
|
396
|
+
pub(crate) using_rust_sdk: bool,
|
|
397
|
+
pub(crate) make_poll_stream_interminable: bool,
|
|
390
398
|
}
|
|
391
399
|
|
|
392
400
|
impl MockPollCfg {
|
|
393
|
-
pub fn new(
|
|
401
|
+
pub(crate) fn new(
|
|
394
402
|
hists: Vec<FakeWfResponses>,
|
|
395
403
|
enforce_correct_number_of_polls: bool,
|
|
396
404
|
num_expected_fails: usize,
|
|
@@ -410,20 +418,20 @@ impl MockPollCfg {
|
|
|
410
418
|
}
|
|
411
419
|
|
|
412
420
|
/// Builds a config which will hand out each WFT in the history builder one by one
|
|
413
|
-
pub fn from_hist_builder(t: TestHistoryBuilder) -> Self {
|
|
421
|
+
pub(crate) fn from_hist_builder(t: TestHistoryBuilder) -> Self {
|
|
414
422
|
let full_hist_info = t.get_full_history_info().unwrap();
|
|
415
423
|
let tasks = 1..=full_hist_info.wf_task_count();
|
|
416
424
|
Self::from_resp_batches("fake_wf_id", t, tasks, mock_workflow_client())
|
|
417
425
|
}
|
|
418
426
|
|
|
419
|
-
pub fn from_resps(
|
|
427
|
+
pub(crate) fn from_resps(
|
|
420
428
|
t: TestHistoryBuilder,
|
|
421
429
|
resps: impl IntoIterator<Item = impl Into<ResponseType>>,
|
|
422
430
|
) -> Self {
|
|
423
431
|
Self::from_resp_batches("fake_wf_id", t, resps, mock_workflow_client())
|
|
424
432
|
}
|
|
425
433
|
|
|
426
|
-
pub fn from_resp_batches(
|
|
434
|
+
pub(crate) fn from_resp_batches(
|
|
427
435
|
wf_id: &str,
|
|
428
436
|
t: TestHistoryBuilder,
|
|
429
437
|
resps: impl IntoIterator<Item = impl Into<ResponseType>>,
|
|
@@ -447,7 +455,7 @@ impl MockPollCfg {
|
|
|
447
455
|
}
|
|
448
456
|
}
|
|
449
457
|
|
|
450
|
-
pub fn completion_asserts_from_expectations(
|
|
458
|
+
pub(crate) fn completion_asserts_from_expectations(
|
|
451
459
|
&mut self,
|
|
452
460
|
builder_fn: impl FnOnce(CompletionAssertsBuilder<'_>),
|
|
453
461
|
) {
|
|
@@ -464,8 +472,9 @@ pub(crate) struct CompletionAssertsBuilder<'a> {
|
|
|
464
472
|
dest: &'a mut Option<Box<dyn FnMut(&WorkflowTaskCompletion) + Send>>,
|
|
465
473
|
assertions: VecDeque<Box<dyn FnOnce(&WorkflowTaskCompletion) + Send>>,
|
|
466
474
|
}
|
|
475
|
+
|
|
467
476
|
impl CompletionAssertsBuilder<'_> {
|
|
468
|
-
pub fn then(
|
|
477
|
+
pub(crate) fn then(
|
|
469
478
|
&mut self,
|
|
470
479
|
assert: impl FnOnce(&WorkflowTaskCompletion) + Send + 'static,
|
|
471
480
|
) -> &mut Self {
|
|
@@ -473,6 +482,7 @@ impl CompletionAssertsBuilder<'_> {
|
|
|
473
482
|
self
|
|
474
483
|
}
|
|
475
484
|
}
|
|
485
|
+
|
|
476
486
|
impl Drop for CompletionAssertsBuilder<'_> {
|
|
477
487
|
fn drop(&mut self) {
|
|
478
488
|
let mut asserts = std::mem::take(&mut self.assertions);
|
|
@@ -485,27 +495,32 @@ impl Drop for CompletionAssertsBuilder<'_> {
|
|
|
485
495
|
}
|
|
486
496
|
|
|
487
497
|
#[derive(Default, Clone)]
|
|
488
|
-
pub struct OutstandingWFTMap {
|
|
498
|
+
pub(crate) struct OutstandingWFTMap {
|
|
489
499
|
map: Arc<RwLock<BiMap<String, TaskToken>>>,
|
|
490
500
|
waker: Arc<Notify>,
|
|
491
501
|
all_work_delivered: Arc<AtomicBool>,
|
|
492
502
|
}
|
|
503
|
+
|
|
493
504
|
impl OutstandingWFTMap {
|
|
494
505
|
fn has_run(&self, run_id: &str) -> bool {
|
|
495
506
|
self.map.read().contains_left(run_id)
|
|
496
507
|
}
|
|
508
|
+
|
|
497
509
|
fn put_token(&self, run_id: String, token: TaskToken) {
|
|
498
510
|
self.map.write().insert(run_id, token);
|
|
499
511
|
}
|
|
512
|
+
|
|
500
513
|
fn release_token(&self, token: &TaskToken) {
|
|
501
514
|
self.map.write().remove_by_right(token);
|
|
502
515
|
self.waker.notify_one();
|
|
503
516
|
}
|
|
504
|
-
|
|
517
|
+
|
|
518
|
+
pub(crate) fn release_run(&self, run_id: &str) {
|
|
505
519
|
self.map.write().remove_by_left(run_id);
|
|
506
520
|
self.waker.notify_waiters();
|
|
507
521
|
}
|
|
508
|
-
|
|
522
|
+
|
|
523
|
+
pub(crate) fn all_work_delivered(&self) -> bool {
|
|
509
524
|
self.all_work_delivered.load(Ordering::Acquire)
|
|
510
525
|
}
|
|
511
526
|
}
|
|
@@ -690,10 +705,11 @@ pub(crate) fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder {
|
|
|
690
705
|
mh
|
|
691
706
|
}
|
|
692
707
|
|
|
693
|
-
pub struct QueueResponse<T> {
|
|
694
|
-
pub resp: T,
|
|
695
|
-
pub delay_until: Option<BoxFuture<'static, ()>>,
|
|
708
|
+
pub(crate) struct QueueResponse<T> {
|
|
709
|
+
pub(crate) resp: T,
|
|
710
|
+
pub(crate) delay_until: Option<BoxFuture<'static, ()>>,
|
|
696
711
|
}
|
|
712
|
+
|
|
697
713
|
impl<T> From<T> for QueueResponse<T> {
|
|
698
714
|
fn from(resp: T) -> Self {
|
|
699
715
|
QueueResponse {
|
|
@@ -732,7 +748,7 @@ where
|
|
|
732
748
|
}
|
|
733
749
|
}
|
|
734
750
|
|
|
735
|
-
pub fn hist_to_poll_resp(
|
|
751
|
+
pub(crate) fn hist_to_poll_resp(
|
|
736
752
|
t: &TestHistoryBuilder,
|
|
737
753
|
wf_id: impl Into<String>,
|
|
738
754
|
response_type: ResponseType,
|
|
@@ -828,18 +844,23 @@ pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
|
|
|
828
844
|
}
|
|
829
845
|
|
|
830
846
|
let mut res = worker.poll_workflow_activation().await.unwrap();
|
|
831
|
-
|
|
847
|
+
if res.jobs.iter().any(|j| {
|
|
848
|
+
matches!(
|
|
849
|
+
j.variant,
|
|
850
|
+
Some(workflow_activation_job::Variant::RemoveFromCache(_))
|
|
851
|
+
)
|
|
852
|
+
}) && res.jobs.len() > 1
|
|
853
|
+
{
|
|
854
|
+
panic!("Saw an activation with an eviction & other work! {res:?}");
|
|
855
|
+
}
|
|
856
|
+
let is_eviction = res.is_only_eviction();
|
|
832
857
|
|
|
833
858
|
let mut do_release = false;
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
//
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
res.jobs.len() - 1,
|
|
840
|
-
"Eviction job was not last job in job list"
|
|
841
|
-
);
|
|
842
|
-
res.jobs.remove(eviction_job_ix);
|
|
859
|
+
|
|
860
|
+
if is_eviction {
|
|
861
|
+
// If the job is an eviction, clear it, since in the tests we don't explicitly
|
|
862
|
+
// specify evict assertions
|
|
863
|
+
res.jobs.clear();
|
|
843
864
|
do_release = true;
|
|
844
865
|
}
|
|
845
866
|
|
|
@@ -870,7 +891,7 @@ pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
|
|
|
870
891
|
}
|
|
871
892
|
// Restart assertions from the beginning if it was an eviction (and workflow execution
|
|
872
893
|
// isn't over)
|
|
873
|
-
if
|
|
894
|
+
if is_eviction && !ends_execution {
|
|
874
895
|
continue 'outer;
|
|
875
896
|
}
|
|
876
897
|
|
|
@@ -45,11 +45,11 @@ enum HeartbeatAction {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
#[derive(Debug)]
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
struct ValidActivityHeartbeat {
|
|
49
|
+
task_token: TaskToken,
|
|
50
|
+
details: Vec<Payload>,
|
|
51
|
+
throttle_interval: Duration,
|
|
52
|
+
timeout_resetter: Option<Arc<Notify>>,
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
#[derive(Debug)]
|
|
@@ -65,7 +65,7 @@ enum HeartbeatExecutorAction {
|
|
|
65
65
|
|
|
66
66
|
/// Errors thrown when heartbeating
|
|
67
67
|
#[derive(thiserror::Error, Debug)]
|
|
68
|
-
pub enum ActivityHeartbeatError {
|
|
68
|
+
pub(crate) enum ActivityHeartbeatError {
|
|
69
69
|
/// Heartbeat referenced an activity that we don't think exists. It may have completed already.
|
|
70
70
|
#[error("Heartbeat has been sent for activity that either completed or never started on this worker.")]
|
|
71
71
|
UnknownActivity,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
abstractions::{dbg_panic,
|
|
2
|
+
abstractions::{dbg_panic, MeteredPermitDealer, OwnedMeteredSemPermit, UsedMeteredSemPermit},
|
|
3
3
|
protosext::ValidScheduleLA,
|
|
4
4
|
retry_logic::RetryPolicyExt,
|
|
5
5
|
worker::workflow::HeartbeatTimeoutMsg,
|
|
@@ -12,9 +12,11 @@ use std::{
|
|
|
12
12
|
collections::{hash_map::Entry, HashMap},
|
|
13
13
|
fmt::{Debug, Formatter},
|
|
14
14
|
pin::Pin,
|
|
15
|
+
sync::Arc,
|
|
15
16
|
task::{Context, Poll},
|
|
16
17
|
time::{Duration, Instant, SystemTime},
|
|
17
18
|
};
|
|
19
|
+
use temporal_sdk_core_api::worker::{LocalActivitySlotInfo, LocalActivitySlotKind, SlotSupplier};
|
|
18
20
|
use temporal_sdk_core_protos::{
|
|
19
21
|
coresdk::{
|
|
20
22
|
activity_result::{Cancellation, Failure as ActFail, Success},
|
|
@@ -47,18 +49,14 @@ pub(crate) enum NextPendingLAAction {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
#[derive(Debug)]
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
_permit: UsedMeteredSemPermit
|
|
52
|
+
struct LocalInFlightActInfo {
|
|
53
|
+
la_info: NewLocalAct,
|
|
54
|
+
dispatch_time: Instant,
|
|
55
|
+
attempt: u32,
|
|
56
|
+
_permit: UsedMeteredSemPermit<LocalActivitySlotKind>,
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
#[derive(Debug, Clone)]
|
|
58
|
-
#[cfg_attr(
|
|
59
|
-
feature = "save_wf_inputs",
|
|
60
|
-
derive(serde::Serialize, serde::Deserialize)
|
|
61
|
-
)]
|
|
62
60
|
pub(crate) enum LocalActivityExecutionResult {
|
|
63
61
|
Completed(Success),
|
|
64
62
|
Failed(ActFail),
|
|
@@ -97,33 +95,30 @@ impl LocalActivityExecutionResult {
|
|
|
97
95
|
..
|
|
98
96
|
}),
|
|
99
97
|
..
|
|
100
|
-
}) => TimeoutType::
|
|
98
|
+
}) => TimeoutType::try_from(*timeout_type).ok(),
|
|
101
99
|
_ => None,
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
#[derive(Debug, Clone)]
|
|
107
|
-
#[cfg_attr(
|
|
108
|
-
feature = "save_wf_inputs",
|
|
109
|
-
derive(serde::Serialize, serde::Deserialize)
|
|
110
|
-
)]
|
|
111
105
|
pub(crate) struct LocalActivityResolution {
|
|
112
|
-
pub seq: u32,
|
|
113
|
-
pub result: LocalActivityExecutionResult,
|
|
114
|
-
pub runtime: Duration,
|
|
115
|
-
pub attempt: u32,
|
|
116
|
-
pub backoff: Option<prost_types::Duration>,
|
|
117
|
-
pub original_schedule_time: Option<SystemTime>,
|
|
106
|
+
pub(crate) seq: u32,
|
|
107
|
+
pub(crate) result: LocalActivityExecutionResult,
|
|
108
|
+
pub(crate) runtime: Duration,
|
|
109
|
+
pub(crate) attempt: u32,
|
|
110
|
+
pub(crate) backoff: Option<prost_types::Duration>,
|
|
111
|
+
pub(crate) original_schedule_time: Option<SystemTime>,
|
|
118
112
|
}
|
|
119
113
|
|
|
120
114
|
#[derive(Clone)]
|
|
121
115
|
pub(crate) struct NewLocalAct {
|
|
122
|
-
pub schedule_cmd: ValidScheduleLA,
|
|
123
|
-
pub workflow_type: String,
|
|
124
|
-
pub workflow_exec_info: WorkflowExecution,
|
|
125
|
-
pub schedule_time: SystemTime,
|
|
116
|
+
pub(crate) schedule_cmd: ValidScheduleLA,
|
|
117
|
+
pub(crate) workflow_type: String,
|
|
118
|
+
pub(crate) workflow_exec_info: WorkflowExecution,
|
|
119
|
+
pub(crate) schedule_time: SystemTime,
|
|
126
120
|
}
|
|
121
|
+
|
|
127
122
|
impl Debug for NewLocalAct {
|
|
128
123
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
129
124
|
write!(
|
|
@@ -154,8 +149,8 @@ pub(crate) enum LocalActRequest {
|
|
|
154
149
|
|
|
155
150
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
156
151
|
pub(crate) struct ExecutingLAId {
|
|
157
|
-
pub run_id: String,
|
|
158
|
-
pub seq_num: u32,
|
|
152
|
+
pub(crate) run_id: String,
|
|
153
|
+
pub(crate) seq_num: u32,
|
|
159
154
|
}
|
|
160
155
|
|
|
161
156
|
pub(crate) struct LocalActivityManager {
|
|
@@ -210,7 +205,7 @@ impl LAMData {
|
|
|
210
205
|
|
|
211
206
|
impl LocalActivityManager {
|
|
212
207
|
pub(crate) fn new(
|
|
213
|
-
|
|
208
|
+
slot_supplier: Arc<dyn SlotSupplier<SlotKind = LocalActivitySlotKind> + Send + Sync>,
|
|
214
209
|
namespace: String,
|
|
215
210
|
heartbeat_timeout_tx: UnboundedSender<HeartbeatTimeoutMsg>,
|
|
216
211
|
metrics_context: MetricsContext,
|
|
@@ -218,11 +213,7 @@ impl LocalActivityManager {
|
|
|
218
213
|
let (act_req_tx, act_req_rx) = unbounded_channel();
|
|
219
214
|
let (cancels_req_tx, cancels_req_rx) = unbounded_channel();
|
|
220
215
|
let shutdown_complete_tok = CancellationToken::new();
|
|
221
|
-
let semaphore =
|
|
222
|
-
max_concurrent,
|
|
223
|
-
metrics_context,
|
|
224
|
-
MetricsContext::available_task_slots,
|
|
225
|
-
);
|
|
216
|
+
let semaphore = MeteredPermitDealer::new(slot_supplier, metrics_context, None);
|
|
226
217
|
Self {
|
|
227
218
|
namespace,
|
|
228
219
|
rcvs: tokio::sync::Mutex::new(RcvChans::new(
|
|
@@ -247,13 +238,11 @@ impl LocalActivityManager {
|
|
|
247
238
|
|
|
248
239
|
#[cfg(test)]
|
|
249
240
|
fn test(max_concurrent: usize) -> Self {
|
|
241
|
+
use crate::worker::tuner::FixedSizeSlotSupplier;
|
|
242
|
+
|
|
243
|
+
let ss = Arc::new(FixedSizeSlotSupplier::new(max_concurrent));
|
|
250
244
|
let (hb_tx, _hb_rx) = unbounded_channel();
|
|
251
|
-
Self::new(
|
|
252
|
-
max_concurrent,
|
|
253
|
-
"fake_ns".to_string(),
|
|
254
|
-
hb_tx,
|
|
255
|
-
MetricsContext::no_op(),
|
|
256
|
-
)
|
|
245
|
+
Self::new(ss, "fake_ns".to_string(), hb_tx, MetricsContext::no_op())
|
|
257
246
|
}
|
|
258
247
|
|
|
259
248
|
#[cfg(test)]
|
|
@@ -386,7 +375,19 @@ impl LocalActivityManager {
|
|
|
386
375
|
let (new_or_retry, permit) = match self.rcvs.lock().await.next().await? {
|
|
387
376
|
NewOrCancel::Cancel(c) => {
|
|
388
377
|
return match c {
|
|
389
|
-
CancelOrTimeout::Cancel(c) =>
|
|
378
|
+
CancelOrTimeout::Cancel(c) => {
|
|
379
|
+
if self
|
|
380
|
+
.dat
|
|
381
|
+
.lock()
|
|
382
|
+
.outstanding_activity_tasks
|
|
383
|
+
.contains_key(c.task_token.as_slice())
|
|
384
|
+
{
|
|
385
|
+
Some(NextPendingLAAction::Dispatch(c))
|
|
386
|
+
} else {
|
|
387
|
+
// Don't dispatch cancels for things we've already stopped tracking
|
|
388
|
+
None
|
|
389
|
+
}
|
|
390
|
+
}
|
|
390
391
|
CancelOrTimeout::Timeout { run_id, resolution } => {
|
|
391
392
|
let tt = self
|
|
392
393
|
.dat
|
|
@@ -471,7 +472,9 @@ impl LocalActivityManager {
|
|
|
471
472
|
la_info: la_info_for_in_flight_map,
|
|
472
473
|
dispatch_time: Instant::now(),
|
|
473
474
|
attempt,
|
|
474
|
-
_permit: permit.into_used(
|
|
475
|
+
_permit: permit.into_used(LocalActivitySlotInfo {
|
|
476
|
+
activity_type: new_la.workflow_type.as_str(),
|
|
477
|
+
}),
|
|
475
478
|
},
|
|
476
479
|
);
|
|
477
480
|
|
|
@@ -787,7 +790,7 @@ enum CancelOrTimeout {
|
|
|
787
790
|
|
|
788
791
|
#[allow(clippy::large_enum_variant)]
|
|
789
792
|
enum NewOrCancel {
|
|
790
|
-
New(NewOrRetry, OwnedMeteredSemPermit),
|
|
793
|
+
New(NewOrRetry, OwnedMeteredSemPermit<LocalActivitySlotKind>),
|
|
791
794
|
Cancel(CancelOrTimeout),
|
|
792
795
|
}
|
|
793
796
|
|
|
@@ -800,7 +803,7 @@ struct RcvChans {
|
|
|
800
803
|
impl RcvChans {
|
|
801
804
|
fn new(
|
|
802
805
|
new_reqs: UnboundedReceiver<NewOrRetry>,
|
|
803
|
-
new_sem:
|
|
806
|
+
new_sem: MeteredPermitDealer<LocalActivitySlotKind>,
|
|
804
807
|
cancels: UnboundedReceiver<CancelOrTimeout>,
|
|
805
808
|
shutdown_completed: CancellationToken,
|
|
806
809
|
) -> Self {
|