@temporalio/core-bridge 1.15.0 → 1.16.1
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 +172 -70
- package/lib/native.d.ts +1 -1
- package/package.json +2 -2
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.github/workflows/per-pr.yml +6 -6
- package/sdk-core/AGENTS.md +41 -30
- package/sdk-core/Cargo.toml +3 -0
- package/sdk-core/README.md +15 -9
- package/sdk-core/crates/client/Cargo.toml +4 -0
- package/sdk-core/crates/client/README.md +139 -0
- package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
- package/sdk-core/crates/client/src/callback_based.rs +7 -0
- package/sdk-core/crates/client/src/errors.rs +294 -0
- package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
- package/sdk-core/crates/client/src/lib.rs +920 -1326
- package/sdk-core/crates/client/src/metrics.rs +24 -33
- package/sdk-core/crates/client/src/options_structs.rs +457 -0
- package/sdk-core/crates/client/src/replaceable.rs +5 -4
- package/sdk-core/crates/client/src/request_extensions.rs +8 -9
- package/sdk-core/crates/client/src/retry.rs +99 -54
- package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +61 -2
- package/sdk-core/crates/common/build.rs +742 -12
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
- package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
- package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -5
- package/sdk-core/crates/common/src/activity_definition.rs +20 -0
- package/sdk-core/crates/common/src/data_converters.rs +770 -0
- package/sdk-core/crates/common/src/envconfig.rs +5 -0
- package/sdk-core/crates/common/src/lib.rs +15 -211
- package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
- package/sdk-core/crates/common/src/priority.rs +110 -0
- package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
- package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
- package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
- package/sdk-core/crates/common/src/protos/mod.rs +122 -27
- package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
- package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
- package/sdk-core/crates/common/src/telemetry.rs +264 -4
- package/sdk-core/crates/common/src/worker.rs +68 -603
- package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
- package/sdk-core/crates/macros/Cargo.toml +5 -1
- package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
- package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
- package/sdk-core/crates/macros/src/lib.rs +138 -512
- package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
- package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
- package/sdk-core/crates/sdk/Cargo.toml +19 -6
- package/sdk-core/crates/sdk/README.md +415 -0
- package/sdk-core/crates/sdk/src/activities.rs +417 -0
- package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
- package/sdk-core/crates/sdk/src/lib.rs +757 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
- package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
- package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
- package/sdk-core/crates/sdk/src/workflows.rs +711 -0
- package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
- package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
- package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
- package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
- package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
- package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
- package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
- package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
- package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
- package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
- package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
- package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
- package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
- package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
- package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
- package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
- package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
- package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
- package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
- package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
- package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
- package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
- package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
- package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
- package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
- package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
- package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
- package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
- package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +205 -318
- package/src/metrics.rs +22 -30
- package/src/runtime.rs +4 -5
- package/src/worker.rs +16 -19
- package/ts/native.ts +1 -1
- package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
- package/sdk-core/crates/common/src/errors.rs +0 -85
- package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
- package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
- package/sdk-core/crates/sdk/src/app_data.rs +0 -37
- package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
|
@@ -5,27 +5,37 @@
|
|
|
5
5
|
//! We can use `clap` if this needs more arguments / other stuff later on.
|
|
6
6
|
|
|
7
7
|
use prost::Message;
|
|
8
|
-
use temporalio_client::{
|
|
8
|
+
use temporalio_client::{
|
|
9
|
+
Client, ClientOptions, Connection, ConnectionOptions, NamespacedClient, WorkflowExecutionInfo,
|
|
10
|
+
WorkflowFetchHistoryOptions,
|
|
11
|
+
};
|
|
12
|
+
use temporalio_common::protos::temporal::api::history::v1::History;
|
|
9
13
|
use url::Url;
|
|
10
14
|
|
|
11
15
|
#[tokio::main]
|
|
12
16
|
async fn main() -> Result<(), anyhow::Error> {
|
|
13
|
-
let
|
|
14
|
-
let copts = ClientOptions::builder()
|
|
17
|
+
let copts = ConnectionOptions::new(Url::try_from("http://localhost:7233").unwrap())
|
|
15
18
|
.client_name("histfetch")
|
|
16
19
|
.client_version("0.0")
|
|
17
|
-
.target_url(url)
|
|
18
20
|
.build();
|
|
19
|
-
let
|
|
21
|
+
let connection = Connection::connect(copts).await?;
|
|
22
|
+
let client = Client::new(connection, ClientOptions::new("default").build())?;
|
|
20
23
|
let wf_id = std::env::args()
|
|
21
24
|
.nth(1)
|
|
22
25
|
.expect("must provide workflow id as only argument");
|
|
23
|
-
let run_id = std::env::args().nth(2);
|
|
24
|
-
let
|
|
25
|
-
.
|
|
26
|
+
let run_id = std::env::args().nth(2).filter(|s| !s.is_empty());
|
|
27
|
+
let handle = WorkflowExecutionInfo {
|
|
28
|
+
namespace: client.namespace(),
|
|
29
|
+
workflow_id: wf_id.clone(),
|
|
30
|
+
run_id,
|
|
31
|
+
first_execution_run_id: None,
|
|
32
|
+
}
|
|
33
|
+
.bind_untyped(client);
|
|
34
|
+
let events = handle
|
|
35
|
+
.fetch_history(WorkflowFetchHistoryOptions::default())
|
|
26
36
|
.await?
|
|
27
|
-
.
|
|
28
|
-
|
|
37
|
+
.into_events();
|
|
38
|
+
let hist = History { events };
|
|
29
39
|
// Serialize history to file
|
|
30
40
|
let byteified = hist.encode_to_vec();
|
|
31
41
|
tokio::fs::write(format!("{wf_id}_history.bin"), &byteified).await?;
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
#![allow(clippy::upper_case_acronyms)]
|
|
3
3
|
|
|
4
4
|
//! This crate provides a basis for creating new Temporal SDKs without completely starting from
|
|
5
|
-
//! scratch
|
|
5
|
+
//! scratch. APIs provided by this crate are not considered stable and may break at any time.
|
|
6
|
+
//!
|
|
7
|
+
//! If you are looking for the Temporal Rust SDK, please use `temporalio-sdk`.
|
|
6
8
|
|
|
7
9
|
#[cfg(test)]
|
|
8
10
|
#[macro_use]
|
|
@@ -32,41 +34,38 @@ mod core_tests;
|
|
|
32
34
|
#[macro_use]
|
|
33
35
|
pub mod test_help;
|
|
34
36
|
|
|
35
|
-
pub
|
|
36
|
-
|
|
37
|
-
pub use pollers::{
|
|
38
|
-
Client, ClientOptions, ClientTlsOptions, RetryClient, RetryOptions, TlsOptions,
|
|
39
|
-
WorkflowClientTrait,
|
|
37
|
+
pub use crate::worker::client::{
|
|
38
|
+
PollActivityOptions, PollOptions, PollWorkflowOptions, WorkerClient, WorkflowTaskCompletion,
|
|
40
39
|
};
|
|
40
|
+
pub use pollers::{Client, ClientOptions, ClientTlsOptions, RetryOptions, TlsOptions};
|
|
41
41
|
pub use temporalio_common::protos::TaskToken;
|
|
42
42
|
pub use url::Url;
|
|
43
43
|
pub use worker::{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
ActivitySlotKind, CompleteActivityError, CompleteNexusError, CompleteWfError,
|
|
45
|
+
FixedSizeSlotSupplier, LocalActivitySlotKind, NexusSlotKind, PollError, PollerBehavior,
|
|
46
|
+
ResourceBasedSlotsOptions, ResourceBasedSlotsOptionsBuilder, ResourceBasedTuner,
|
|
47
|
+
ResourceSlotOptions, SlotInfo, SlotInfoTrait, SlotKind, SlotKindType, SlotMarkUsedContext,
|
|
48
|
+
SlotReleaseContext, SlotReservationContext, SlotSupplier, SlotSupplierOptions,
|
|
49
|
+
SlotSupplierPermit, TunerBuilder, TunerHolder, TunerHolderOptions, TunerHolderOptionsBuilder,
|
|
50
|
+
Worker, WorkerConfig, WorkerConfigBuilder, WorkerTuner, WorkerValidationError,
|
|
51
|
+
WorkerVersioningStrategy, WorkflowErrorType, WorkflowSlotKind,
|
|
47
52
|
};
|
|
48
53
|
|
|
49
|
-
/// Expose [WorkerClient] symbols
|
|
50
|
-
pub use crate::worker::client::{
|
|
51
|
-
PollActivityOptions, PollOptions, PollWorkflowOptions, WorkerClient, WorkflowTaskCompletion,
|
|
52
|
-
};
|
|
53
54
|
use crate::{
|
|
54
55
|
replay::{HistoryForReplay, ReplayWorkerInput},
|
|
55
|
-
telemetry::
|
|
56
|
-
TelemetryInstance, metrics::MetricsContext, remove_trace_subscriber_for_current_thread,
|
|
57
|
-
set_trace_subscriber_for_current_thread, telemetry_init,
|
|
58
|
-
},
|
|
56
|
+
telemetry::metrics::MetricsContext,
|
|
59
57
|
worker::client::WorkerClientBag,
|
|
60
58
|
};
|
|
61
59
|
use anyhow::bail;
|
|
62
60
|
use futures_util::Stream;
|
|
63
61
|
use std::{sync::Arc, time::Duration};
|
|
64
|
-
use temporalio_client::{
|
|
62
|
+
use temporalio_client::{Connection, SharedReplaceableClient};
|
|
65
63
|
use temporalio_common::{
|
|
66
|
-
Worker as WorkerTrait,
|
|
67
|
-
errors::{CompleteActivityError, PollError},
|
|
68
64
|
protos::coresdk::ActivityHeartbeat,
|
|
69
|
-
telemetry::
|
|
65
|
+
telemetry::{
|
|
66
|
+
TelemetryInstance, TelemetryOptions, remove_trace_subscriber_for_current_thread,
|
|
67
|
+
set_trace_subscriber_for_current_thread, telemetry_init,
|
|
68
|
+
},
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
/// Initialize a worker bound to a task queue.
|
|
@@ -75,44 +74,37 @@ use temporalio_common::{
|
|
|
75
74
|
/// After the worker is initialized, you should use [CoreRuntime::tokio_handle] to run the worker's
|
|
76
75
|
/// async functions.
|
|
77
76
|
///
|
|
78
|
-
/// Lang implementations
|
|
79
|
-
///
|
|
80
|
-
///
|
|
81
|
-
|
|
82
|
-
/// [ClientOptions::connect_no_namespace], not [ClientOptions::connect].
|
|
83
|
-
pub fn init_worker<CT>(
|
|
77
|
+
/// Lang implementations must pass in a [Client] When they do so, this function will always
|
|
78
|
+
/// overwrite the client retry configuration, force the client to use the namespace defined in the
|
|
79
|
+
/// worker config, and set the client identity appropriately.
|
|
80
|
+
pub fn init_worker(
|
|
84
81
|
runtime: &CoreRuntime,
|
|
85
82
|
worker_config: WorkerConfig,
|
|
86
|
-
|
|
87
|
-
) -> Result<Worker, anyhow::Error>
|
|
88
|
-
where
|
|
89
|
-
CT: Into<sealed::AnyClient>,
|
|
90
|
-
{
|
|
83
|
+
mut connection: Connection,
|
|
84
|
+
) -> Result<Worker, anyhow::Error> {
|
|
91
85
|
let namespace = worker_config.namespace.clone();
|
|
92
86
|
if namespace.is_empty() {
|
|
93
87
|
bail!("Worker namespace cannot be empty");
|
|
94
88
|
}
|
|
95
89
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
client,
|
|
101
|
-
)),
|
|
102
|
-
RetryOptions::default(),
|
|
90
|
+
*connection.retry_options_mut() = RetryOptions::default();
|
|
91
|
+
init_worker_client(
|
|
92
|
+
&mut connection,
|
|
93
|
+
worker_config.client_identity_override.clone(),
|
|
103
94
|
);
|
|
104
|
-
let
|
|
105
|
-
let
|
|
106
|
-
|
|
95
|
+
let client = SharedReplaceableClient::new(connection);
|
|
96
|
+
let client_ident = client.inner_cow().identity().to_owned();
|
|
107
97
|
if client_ident.is_empty() {
|
|
108
98
|
bail!("Client identity cannot be empty. Either lang or user should be setting this value");
|
|
109
99
|
}
|
|
100
|
+
let sticky_q = sticky_q_name_for_worker(&client_ident, worker_config.max_cached_workflows);
|
|
110
101
|
|
|
102
|
+
let worker_instance_key = uuid::Uuid::new_v4();
|
|
111
103
|
let client_bag = Arc::new(WorkerClientBag::new(
|
|
112
104
|
client,
|
|
113
105
|
namespace.clone(),
|
|
114
|
-
client_ident.clone(),
|
|
115
106
|
worker_config.versioning_strategy.clone(),
|
|
107
|
+
worker_instance_key,
|
|
116
108
|
));
|
|
117
109
|
|
|
118
110
|
Worker::new(
|
|
@@ -141,19 +133,13 @@ where
|
|
|
141
133
|
rwi.into_core_worker()
|
|
142
134
|
}
|
|
143
135
|
|
|
144
|
-
pub(crate) fn init_worker_client
|
|
145
|
-
|
|
136
|
+
pub(crate) fn init_worker_client(
|
|
137
|
+
connection: &mut Connection,
|
|
146
138
|
client_identity_override: Option<String>,
|
|
147
|
-
|
|
148
|
-
) -> Client
|
|
149
|
-
where
|
|
150
|
-
CT: Into<sealed::AnyClient>,
|
|
151
|
-
{
|
|
152
|
-
let mut client = Client::new(*client.into().into_inner(), namespace.clone());
|
|
139
|
+
) {
|
|
153
140
|
if let Some(ref id_override) = client_identity_override {
|
|
154
|
-
|
|
141
|
+
connection.identity_mut().clone_from(id_override);
|
|
155
142
|
}
|
|
156
|
-
client
|
|
157
143
|
}
|
|
158
144
|
|
|
159
145
|
/// Creates a unique sticky queue name for a worker, iff the config allows for 1 or more cached
|
|
@@ -173,63 +159,6 @@ pub(crate) fn sticky_q_name_for_worker(
|
|
|
173
159
|
}
|
|
174
160
|
}
|
|
175
161
|
|
|
176
|
-
mod sealed {
|
|
177
|
-
use super::*;
|
|
178
|
-
use temporalio_client::{SharedReplaceableClient, TemporalServiceClient};
|
|
179
|
-
|
|
180
|
-
/// Allows passing different kinds of clients into things that want to be flexible. Motivating
|
|
181
|
-
/// use-case was worker initialization.
|
|
182
|
-
///
|
|
183
|
-
/// Needs to exist in this crate to avoid blanket impl conflicts.
|
|
184
|
-
pub struct AnyClient {
|
|
185
|
-
pub(crate) inner: Box<ConfiguredClient<TemporalServiceClient>>,
|
|
186
|
-
}
|
|
187
|
-
impl AnyClient {
|
|
188
|
-
pub(crate) fn into_inner(self) -> Box<ConfiguredClient<TemporalServiceClient>> {
|
|
189
|
-
self.inner
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
impl From<ConfiguredClient<TemporalServiceClient>> for AnyClient {
|
|
194
|
-
fn from(c: ConfiguredClient<TemporalServiceClient>) -> Self {
|
|
195
|
-
Self { inner: Box::new(c) }
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
impl From<Client> for AnyClient {
|
|
200
|
-
fn from(c: Client) -> Self {
|
|
201
|
-
c.into_inner().into()
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
impl<T> From<RetryClient<T>> for AnyClient
|
|
206
|
-
where
|
|
207
|
-
T: Into<AnyClient>,
|
|
208
|
-
{
|
|
209
|
-
fn from(c: RetryClient<T>) -> Self {
|
|
210
|
-
c.into_inner().into()
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
impl<T> From<SharedReplaceableClient<T>> for AnyClient
|
|
215
|
-
where
|
|
216
|
-
T: Into<AnyClient> + Clone + Send + Sync,
|
|
217
|
-
{
|
|
218
|
-
fn from(c: SharedReplaceableClient<T>) -> Self {
|
|
219
|
-
c.inner_clone().into()
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
impl<T> From<Arc<T>> for AnyClient
|
|
224
|
-
where
|
|
225
|
-
T: Into<AnyClient> + Clone,
|
|
226
|
-
{
|
|
227
|
-
fn from(c: Arc<T>) -> Self {
|
|
228
|
-
Arc::unwrap_or_clone(c).into()
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
162
|
/// Holds shared state/components needed to back instances of workers and clients. More than one
|
|
234
163
|
/// may be instantiated, but typically only one is needed. More than one runtime instance may be
|
|
235
164
|
/// useful if multiple different telemetry settings are required.
|
|
@@ -240,7 +169,8 @@ pub struct CoreRuntime {
|
|
|
240
169
|
heartbeat_interval: Option<Duration>,
|
|
241
170
|
}
|
|
242
171
|
|
|
243
|
-
/// Holds telemetry options, as well as worker heartbeat_interval. Construct with
|
|
172
|
+
/// Holds telemetry options, as well as worker heartbeat_interval. Construct with
|
|
173
|
+
/// [RuntimeOptions::builder]
|
|
244
174
|
#[derive(Default, bon::Builder)]
|
|
245
175
|
#[builder(finish_fn(vis = "", name = build_internal))]
|
|
246
176
|
#[non_exhaustive]
|
|
@@ -3,23 +3,18 @@ mod poll_buffer;
|
|
|
3
3
|
pub(crate) use poll_buffer::{
|
|
4
4
|
ActivityTaskOptions, LongPollBuffer, WorkflowTaskOptions, WorkflowTaskPoller,
|
|
5
5
|
};
|
|
6
|
-
pub use temporalio_client::{
|
|
7
|
-
Client, ClientOptions, ClientTlsOptions, RetryClient, RetryOptions, TlsOptions,
|
|
8
|
-
WorkflowClientTrait,
|
|
9
|
-
};
|
|
6
|
+
pub use temporalio_client::{Client, ClientOptions, ClientTlsOptions, RetryOptions, TlsOptions};
|
|
10
7
|
|
|
11
8
|
use crate::{
|
|
12
9
|
abstractions::{OwnedMeteredSemPermit, TrackedOwnedMeteredSemPermit},
|
|
13
10
|
telemetry::metrics::MetricsContext,
|
|
11
|
+
worker::{ActivitySlotKind, NexusSlotKind, SlotKind, WorkflowSlotKind},
|
|
14
12
|
};
|
|
15
13
|
use anyhow::{anyhow, bail};
|
|
16
14
|
use futures_util::{Stream, stream};
|
|
17
15
|
use std::{fmt::Debug, marker::PhantomData};
|
|
18
|
-
use temporalio_common::{
|
|
19
|
-
|
|
20
|
-
PollActivityTaskQueueResponse, PollNexusTaskQueueResponse, PollWorkflowTaskQueueResponse,
|
|
21
|
-
},
|
|
22
|
-
worker::{ActivitySlotKind, NexusSlotKind, SlotKind, WorkflowSlotKind},
|
|
16
|
+
use temporalio_common::protos::temporal::api::workflowservice::v1::{
|
|
17
|
+
PollActivityTaskQueueResponse, PollNexusTaskQueueResponse, PollWorkflowTaskQueueResponse,
|
|
23
18
|
};
|
|
24
19
|
use tokio::select;
|
|
25
20
|
use tokio_util::sync::CancellationToken;
|
|
@@ -2,7 +2,8 @@ use crate::{
|
|
|
2
2
|
abstractions::{ActiveCounter, MeteredPermitDealer, OwnedMeteredSemPermit, dbg_panic},
|
|
3
3
|
pollers::{self, Poller},
|
|
4
4
|
worker::{
|
|
5
|
-
WFTPollerShared,
|
|
5
|
+
ActivitySlotKind, NexusSlotKind, PollerBehavior, SlotKind, WFTPollerShared,
|
|
6
|
+
WorkflowSlotKind,
|
|
6
7
|
client::{PollActivityOptions, PollOptions, PollWorkflowOptions, WorkerClient},
|
|
7
8
|
},
|
|
8
9
|
};
|
|
@@ -23,15 +24,11 @@ use std::{
|
|
|
23
24
|
use temporalio_client::{
|
|
24
25
|
ERROR_RETURNED_DUE_TO_SHORT_CIRCUIT, request_extensions::NoRetryOnMatching,
|
|
25
26
|
};
|
|
26
|
-
use temporalio_common::{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
PollActivityTaskQueueResponse, PollNexusTaskQueueResponse,
|
|
31
|
-
PollWorkflowTaskQueueResponse,
|
|
32
|
-
},
|
|
27
|
+
use temporalio_common::protos::temporal::api::{
|
|
28
|
+
taskqueue::v1::PollerScalingDecision,
|
|
29
|
+
workflowservice::v1::{
|
|
30
|
+
PollActivityTaskQueueResponse, PollNexusTaskQueueResponse, PollWorkflowTaskQueueResponse,
|
|
33
31
|
},
|
|
34
|
-
worker::{ActivitySlotKind, NexusSlotKind, PollerBehavior, SlotKind, WorkflowSlotKind},
|
|
35
32
|
};
|
|
36
33
|
use tokio::{
|
|
37
34
|
sync::{
|
|
@@ -80,6 +77,7 @@ impl LongPollBuffer<PollWorkflowTaskQueueResponse, WorkflowSlotKind> {
|
|
|
80
77
|
num_pollers_handler: Option<impl Fn(usize) + Send + Sync + 'static>,
|
|
81
78
|
options: WorkflowTaskOptions,
|
|
82
79
|
last_successful_poll_time: Arc<AtomicCell<Option<SystemTime>>>,
|
|
80
|
+
graceful_poll_shutdown: Arc<AtomicBool>,
|
|
83
81
|
) -> Self {
|
|
84
82
|
let is_sticky = sticky_queue.is_some();
|
|
85
83
|
let poll_scaler = PollScaler::new(
|
|
@@ -142,6 +140,7 @@ impl LongPollBuffer<PollWorkflowTaskQueueResponse, WorkflowSlotKind> {
|
|
|
142
140
|
poll_scaler,
|
|
143
141
|
pre_permit_delay,
|
|
144
142
|
post_poll_fn,
|
|
143
|
+
graceful_poll_shutdown,
|
|
145
144
|
)
|
|
146
145
|
}
|
|
147
146
|
}
|
|
@@ -157,6 +156,7 @@ impl LongPollBuffer<PollActivityTaskQueueResponse, ActivitySlotKind> {
|
|
|
157
156
|
num_pollers_handler: Option<impl Fn(usize) + Send + Sync + 'static>,
|
|
158
157
|
options: ActivityTaskOptions,
|
|
159
158
|
last_successful_poll_time: Arc<AtomicCell<Option<SystemTime>>>,
|
|
159
|
+
graceful_poll_shutdown: Arc<AtomicBool>,
|
|
160
160
|
) -> Self {
|
|
161
161
|
let pre_permit_delay = options
|
|
162
162
|
.max_worker_acts_per_second
|
|
@@ -209,6 +209,7 @@ impl LongPollBuffer<PollActivityTaskQueueResponse, ActivitySlotKind> {
|
|
|
209
209
|
poll_scaler,
|
|
210
210
|
pre_permit_delay,
|
|
211
211
|
None::<fn(&PollActivityTaskQueueResponse)>,
|
|
212
|
+
graceful_poll_shutdown,
|
|
212
213
|
)
|
|
213
214
|
}
|
|
214
215
|
}
|
|
@@ -224,6 +225,7 @@ impl LongPollBuffer<PollNexusTaskQueueResponse, NexusSlotKind> {
|
|
|
224
225
|
num_pollers_handler: Option<impl Fn(usize) + Send + Sync + 'static>,
|
|
225
226
|
last_successful_poll_time: Arc<AtomicCell<Option<SystemTime>>>,
|
|
226
227
|
send_heartbeat: bool,
|
|
228
|
+
graceful_poll_shutdown: Arc<AtomicBool>,
|
|
227
229
|
) -> Self {
|
|
228
230
|
let no_retry = if matches!(poller_behavior, PollerBehavior::Autoscaling { .. }) {
|
|
229
231
|
Some(NoRetryOnMatching {
|
|
@@ -260,12 +262,13 @@ impl LongPollBuffer<PollNexusTaskQueueResponse, NexusSlotKind> {
|
|
|
260
262
|
),
|
|
261
263
|
None::<fn() -> BoxFuture<'static, ()>>,
|
|
262
264
|
None::<fn(&PollNexusTaskQueueResponse)>,
|
|
265
|
+
graceful_poll_shutdown,
|
|
263
266
|
)
|
|
264
267
|
}
|
|
265
268
|
}
|
|
266
269
|
|
|
267
270
|
// Simple way to test this w/o plumbing options through. This will be removed after
|
|
268
|
-
// the proper server implementation for
|
|
271
|
+
// the proper server implementation for terminating polls on worker shutdown exists.
|
|
269
272
|
#[cfg(test)]
|
|
270
273
|
use std::cell::RefCell;
|
|
271
274
|
#[cfg(test)]
|
|
@@ -285,6 +288,7 @@ where
|
|
|
285
288
|
mut poll_scaler: PollScaler<F>,
|
|
286
289
|
pre_permit_delay: Option<impl Fn() -> DelayFut + Send + Sync + 'static>,
|
|
287
290
|
post_poll_fn: Option<impl Fn(&T) + Send + Sync + 'static>,
|
|
291
|
+
graceful_shutdown: Arc<AtomicBool>,
|
|
288
292
|
) -> Self
|
|
289
293
|
where
|
|
290
294
|
FT: Future<Output = pollers::Result<T>> + Send,
|
|
@@ -355,19 +359,22 @@ where
|
|
|
355
359
|
} else {
|
|
356
360
|
None
|
|
357
361
|
};
|
|
362
|
+
let graceful_shutdown = graceful_shutdown.clone();
|
|
358
363
|
let poll_task = tokio::spawn(async move {
|
|
359
364
|
let shutdown_clone = shutdown.clone();
|
|
360
365
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
+
let r = if graceful_shutdown.load(Ordering::Relaxed) {
|
|
367
|
+
pf(timeout_override).await
|
|
368
|
+
} else {
|
|
369
|
+
let poll_interruptor = shutdown.cancelled().then(|_| async move {
|
|
370
|
+
if let Some(w) = poll_shutdown_interrupt_wait {
|
|
371
|
+
tokio::time::sleep(w).await;
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
tokio::select! {
|
|
375
|
+
r = pf(timeout_override) => r,
|
|
376
|
+
_ = poll_interruptor => return,
|
|
366
377
|
}
|
|
367
|
-
});
|
|
368
|
-
let r = tokio::select! {
|
|
369
|
-
r = pf(timeout_override) => r,
|
|
370
|
-
_ = poll_interruptor => return,
|
|
371
378
|
};
|
|
372
379
|
if let Ok(r) = &r
|
|
373
380
|
&& let Some(ppf) = post_pf.as_ref()
|
|
@@ -846,6 +853,7 @@ mod tests {
|
|
|
846
853
|
wft_poller_shared: Some(Arc::new(WFTPollerShared::new(Some(10)))),
|
|
847
854
|
},
|
|
848
855
|
Arc::new(AtomicCell::new(None)),
|
|
856
|
+
Arc::new(AtomicBool::new(false)),
|
|
849
857
|
);
|
|
850
858
|
|
|
851
859
|
// Poll a bunch of times, "interrupting" it each time, we should only actually have polled
|
|
@@ -902,6 +910,7 @@ mod tests {
|
|
|
902
910
|
wft_poller_shared: Some(Arc::new(WFTPollerShared::new(Some(1)))),
|
|
903
911
|
},
|
|
904
912
|
Arc::new(AtomicCell::new(None)),
|
|
913
|
+
Arc::new(AtomicBool::new(false)),
|
|
905
914
|
);
|
|
906
915
|
|
|
907
916
|
// Should not see error, unwraps should get empty response
|
|
@@ -978,6 +987,7 @@ mod tests {
|
|
|
978
987
|
wft_poller_shared: Some(Arc::new(WFTPollerShared::new(Some(10)))),
|
|
979
988
|
},
|
|
980
989
|
Arc::new(AtomicCell::new(None)),
|
|
990
|
+
Arc::new(AtomicBool::new(false)),
|
|
981
991
|
);
|
|
982
992
|
|
|
983
993
|
let first_task = pb.poll().await.expect("Should get first task");
|
|
@@ -1083,6 +1093,7 @@ mod tests {
|
|
|
1083
1093
|
wft_poller_shared: Some(Arc::new(WFTPollerShared::new(Some(10)))),
|
|
1084
1094
|
},
|
|
1085
1095
|
Arc::new(AtomicCell::new(None)),
|
|
1096
|
+
Arc::new(AtomicBool::new(false)),
|
|
1086
1097
|
));
|
|
1087
1098
|
|
|
1088
1099
|
// Trigger the first poll to initialize and get the scaling decision
|
|
@@ -1111,4 +1122,92 @@ mod tests {
|
|
|
1111
1122
|
.shutdown()
|
|
1112
1123
|
.await;
|
|
1113
1124
|
}
|
|
1125
|
+
|
|
1126
|
+
#[rstest]
|
|
1127
|
+
#[case::graceful(true)]
|
|
1128
|
+
#[case::legacy(false)]
|
|
1129
|
+
#[tokio::test]
|
|
1130
|
+
async fn inflight_poll_survives_shutdown_only_when_graceful(#[case] graceful: bool) {
|
|
1131
|
+
let mut mock_client = mock_manual_worker_client();
|
|
1132
|
+
let task_started = Arc::new(Notify::new());
|
|
1133
|
+
let task_started_clone = task_started.clone();
|
|
1134
|
+
let task_complete = Arc::new(Notify::new());
|
|
1135
|
+
let task_complete_clone = task_complete.clone();
|
|
1136
|
+
let call_count = Arc::new(AtomicUsize::new(0));
|
|
1137
|
+
let call_count_clone = call_count.clone();
|
|
1138
|
+
|
|
1139
|
+
mock_client
|
|
1140
|
+
.expect_poll_workflow_task()
|
|
1141
|
+
.returning(move |_, _| {
|
|
1142
|
+
let count = call_count_clone.fetch_add(1, Ordering::SeqCst);
|
|
1143
|
+
let started = task_started_clone.clone();
|
|
1144
|
+
let complete = task_complete_clone.clone();
|
|
1145
|
+
async move {
|
|
1146
|
+
match count {
|
|
1147
|
+
0 => Ok(PollWorkflowTaskQueueResponse {
|
|
1148
|
+
task_token: vec![1],
|
|
1149
|
+
..Default::default()
|
|
1150
|
+
}),
|
|
1151
|
+
_ => {
|
|
1152
|
+
started.notify_one();
|
|
1153
|
+
complete.notified().await;
|
|
1154
|
+
Ok(PollWorkflowTaskQueueResponse {
|
|
1155
|
+
task_token: vec![2],
|
|
1156
|
+
..Default::default()
|
|
1157
|
+
})
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
.boxed()
|
|
1162
|
+
});
|
|
1163
|
+
|
|
1164
|
+
let shutdown_token = CancellationToken::new();
|
|
1165
|
+
let pb = LongPollBuffer::new_workflow_task(
|
|
1166
|
+
Arc::new(mock_client),
|
|
1167
|
+
"sometq".to_string(),
|
|
1168
|
+
None,
|
|
1169
|
+
PollerBehavior::SimpleMaximum(1),
|
|
1170
|
+
fixed_size_permit_dealer(10),
|
|
1171
|
+
shutdown_token.clone(),
|
|
1172
|
+
None::<fn(usize)>,
|
|
1173
|
+
WorkflowTaskOptions {
|
|
1174
|
+
wft_poller_shared: None,
|
|
1175
|
+
},
|
|
1176
|
+
Arc::new(AtomicCell::new(None)),
|
|
1177
|
+
Arc::new(AtomicBool::new(graceful)),
|
|
1178
|
+
);
|
|
1179
|
+
|
|
1180
|
+
let first = pb.poll().await.unwrap().unwrap();
|
|
1181
|
+
assert_eq!(first.0.task_token, vec![1]);
|
|
1182
|
+
|
|
1183
|
+
// Wait for second poll to be in-flight
|
|
1184
|
+
task_started.notified().await;
|
|
1185
|
+
|
|
1186
|
+
shutdown_token.cancel();
|
|
1187
|
+
|
|
1188
|
+
if graceful {
|
|
1189
|
+
// Release the poll — simulates server returning empty after ShutdownWorker
|
|
1190
|
+
task_complete.notify_one();
|
|
1191
|
+
|
|
1192
|
+
// Graceful: in-flight poll survives, second task is received
|
|
1193
|
+
let second = tokio::time::timeout(Duration::from_secs(2), pb.poll())
|
|
1194
|
+
.await
|
|
1195
|
+
.expect("graceful poll should complete")
|
|
1196
|
+
.unwrap()
|
|
1197
|
+
.unwrap();
|
|
1198
|
+
assert_eq!(second.0.task_token, vec![2]);
|
|
1199
|
+
} else {
|
|
1200
|
+
// Don't release — the poll should be killed by shutdown token before completing.
|
|
1201
|
+
// Buffer drains to None because the killed poll sends no result.
|
|
1202
|
+
let result = tokio::time::timeout(Duration::from_secs(2), pb.poll())
|
|
1203
|
+
.await
|
|
1204
|
+
.expect("legacy poll should resolve quickly");
|
|
1205
|
+
assert!(
|
|
1206
|
+
result.is_none(),
|
|
1207
|
+
"Legacy shutdown should kill in-flight poll, buffer returns None"
|
|
1208
|
+
);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
pb.shutdown().await;
|
|
1212
|
+
}
|
|
1114
1213
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
pub(crate) mod protocol_messages;
|
|
2
2
|
|
|
3
3
|
use crate::{
|
|
4
|
-
|
|
4
|
+
TaskToken,
|
|
5
5
|
protosext::protocol_messages::IncomingProtocolMessage,
|
|
6
6
|
retry_logic::ValidatedRetryPolicy,
|
|
7
|
-
worker::{LEGACY_QUERY_ID, LocalActivityExecutionResult},
|
|
7
|
+
worker::{CompleteActivityError, LEGACY_QUERY_ID, LocalActivityExecutionResult},
|
|
8
8
|
};
|
|
9
9
|
use anyhow::anyhow;
|
|
10
10
|
use itertools::Itertools;
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
//! users during testing.
|
|
4
4
|
|
|
5
5
|
use crate::{
|
|
6
|
-
Worker,
|
|
6
|
+
Worker, WorkerConfig,
|
|
7
7
|
worker::{
|
|
8
|
-
PostActivateHookData,
|
|
8
|
+
PollerBehavior, PostActivateHookData,
|
|
9
9
|
client::mocks::{MockManualWorkerClient, mock_manual_worker_client},
|
|
10
10
|
},
|
|
11
11
|
};
|
|
@@ -30,7 +30,7 @@ use temporalio_common::{
|
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
|
-
worker::
|
|
33
|
+
worker::WorkerTaskTypes,
|
|
34
34
|
};
|
|
35
35
|
use tokio::sync::{Mutex as TokioMutex, mpsc, mpsc::UnboundedSender};
|
|
36
36
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
|
@@ -126,11 +126,20 @@ where
|
|
|
126
126
|
|
|
127
127
|
/// A history which will be used during replay verification. Since histories do not include the
|
|
128
128
|
/// workflow id, it must be manually attached.
|
|
129
|
-
#[derive(Debug, Clone
|
|
129
|
+
#[derive(Debug, Clone)]
|
|
130
130
|
pub struct HistoryForReplay {
|
|
131
131
|
hist: History,
|
|
132
132
|
workflow_id: String,
|
|
133
133
|
}
|
|
134
|
+
impl HistoryForReplay {
|
|
135
|
+
/// Create a new history from replay from something that looks like a history and a workflow id.
|
|
136
|
+
pub fn new(history: impl Into<History>, workflow_id: impl Into<String>) -> Self {
|
|
137
|
+
Self {
|
|
138
|
+
hist: history.into(),
|
|
139
|
+
workflow_id: workflow_id.into(),
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
134
143
|
impl From<TestHistoryBuilder> for HistoryForReplay {
|
|
135
144
|
fn from(thb: TestHistoryBuilder) -> Self {
|
|
136
145
|
thb.get_full_history_info().unwrap().into()
|
|
@@ -138,7 +147,7 @@ impl From<TestHistoryBuilder> for HistoryForReplay {
|
|
|
138
147
|
}
|
|
139
148
|
impl From<HistoryInfo> for HistoryForReplay {
|
|
140
149
|
fn from(histinfo: HistoryInfo) -> Self {
|
|
141
|
-
HistoryForReplay::new(histinfo
|
|
150
|
+
HistoryForReplay::new(histinfo, "fake".to_owned())
|
|
142
151
|
}
|
|
143
152
|
}
|
|
144
153
|
|