@temporalio/core-bridge 1.14.2-canary-release-testing.0 → 1.16.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 +794 -650
- package/bridge-macros/src/derive_tryintojs.rs +40 -0
- package/lib/native.d.ts +24 -3
- 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/sdk-core/.github/workflows/per-pr.yml +6 -6
- package/sdk-core/AGENTS.md +42 -31
- package/sdk-core/Cargo.toml +4 -1
- package/sdk-core/README.md +19 -13
- 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} +370 -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} +104 -29
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +62 -3
- 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/.github/workflows/create-release.yml +0 -5
- package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/README.md +8 -0
- 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 +3329 -2647
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +2734 -708
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/activity/v1/message.proto +155 -3
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/common/v1/message.proto +8 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +27 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/activity.proto +81 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/event_type.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +15 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +63 -15
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/errordetails/v1/message.proto +8 -0
- 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 +111 -17
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +21 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +20 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/worker/v1/message.proto +4 -7
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflow/v1/message.proto +80 -22
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +347 -23
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +242 -43
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/core_interface.proto +15 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +9 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +8 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +22 -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 +19 -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 +134 -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 +11 -16
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +272 -225
- 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 +278 -19
- package/sdk-core/crates/common/src/worker.rs +68 -636
- 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 +759 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +64 -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 +59 -65
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +45 -54
- 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 +22 -21
- 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 +647 -27
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +46 -41
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +13 -16
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +60 -123
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +411 -32
- 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 +183 -198
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -281
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +35 -16
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- package/sdk-core/crates/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +1 -0
- 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 +11 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +104 -86
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +10 -14
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1175 -241
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +150 -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 +25 -27
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +64 -44
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/patch_state_machine.rs +5 -8
- 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 +28 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +20 -41
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +50 -9
- 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 +281 -236
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +9 -14
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -66
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +306 -268
- 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 +37 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +49 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +447 -300
- 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 +157 -157
- 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 -463
- 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 +389 -265
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +250 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -49
- 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 +437 -327
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -58
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -30
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -251
- 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 +110 -46
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -149
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -32
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1040
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -43
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +402 -245
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +343 -207
- 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 +155 -140
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -113
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -44
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -48
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +365 -242
- package/sdk-core/crates/sdk-core/tests/main.rs +22 -16
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +233 -187
- package/sdk-core/crates/sdk-core/tests/runner.rs +4 -6
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +73 -27
- 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 +8 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +37 -26
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +180 -87
- package/sdk-core/crates/sdk-core-c-bridge/src/lib.rs +89 -5
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +10 -16
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +59 -67
- package/sdk-core/crates/sdk-core-c-bridge/src/testing.rs +10 -10
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +57 -22
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +108 -12
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +9 -52
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +74 -91
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +206 -289
- package/src/helpers/try_into_js.rs +88 -2
- package/src/metrics.rs +277 -35
- package/src/runtime.rs +94 -45
- package/src/testing.rs +9 -16
- package/src/worker.rs +86 -68
- package/ts/native.ts +39 -3
- 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/macros/LICENSE.txt +0 -21
- 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
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
ERROR_RETURNED_DUE_TO_SHORT_CIRCUIT, MESSAGE_TOO_LARGE_KEY,
|
|
3
|
-
|
|
4
|
-
raw::IsUserLongPoll,
|
|
2
|
+
ERROR_RETURNED_DUE_TO_SHORT_CIRCUIT, MESSAGE_TOO_LARGE_KEY,
|
|
3
|
+
grpc::IsUserLongPoll,
|
|
5
4
|
request_extensions::{IsWorkerTaskLongPoll, NoRetryOnMatching, RetryConfigForCall},
|
|
6
5
|
};
|
|
7
|
-
use backoff::{
|
|
6
|
+
use backoff::{
|
|
7
|
+
Clock, SystemClock,
|
|
8
|
+
backoff::Backoff,
|
|
9
|
+
exponential::{self, ExponentialBackoff},
|
|
10
|
+
};
|
|
8
11
|
use futures_retry::{ErrorHandler, FutureRetry, RetryPolicy};
|
|
9
|
-
use std::{
|
|
10
|
-
|
|
12
|
+
use std::{
|
|
13
|
+
error::Error,
|
|
14
|
+
fmt::Debug,
|
|
15
|
+
future::Future,
|
|
16
|
+
time::{Duration, Instant},
|
|
17
|
+
};
|
|
18
|
+
use tonic::Code;
|
|
11
19
|
|
|
12
20
|
/// List of gRPC error codes that client will retry.
|
|
13
21
|
#[doc(hidden)]
|
|
@@ -22,44 +30,77 @@ pub const RETRYABLE_ERROR_CODES: [Code; 7] = [
|
|
|
22
30
|
];
|
|
23
31
|
const LONG_POLL_FATAL_GRACE: Duration = Duration::from_secs(60);
|
|
24
32
|
|
|
25
|
-
///
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
/// Configuration for retrying requests to the server
|
|
34
|
+
#[derive(Clone, Debug, PartialEq)]
|
|
35
|
+
pub struct RetryOptions {
|
|
36
|
+
/// initial wait time before the first retry.
|
|
37
|
+
pub initial_interval: Duration,
|
|
38
|
+
/// randomization jitter that is used as a multiplier for the current retry interval
|
|
39
|
+
/// and is added or subtracted from the interval length.
|
|
40
|
+
pub randomization_factor: f64,
|
|
41
|
+
/// rate at which retry time should be increased, until it reaches max_interval.
|
|
42
|
+
pub multiplier: f64,
|
|
43
|
+
/// maximum amount of time to wait between retries.
|
|
44
|
+
pub max_interval: Duration,
|
|
45
|
+
/// maximum total amount of time requests should be retried for, if None is set then no limit
|
|
46
|
+
/// will be used.
|
|
47
|
+
pub max_elapsed_time: Option<Duration>,
|
|
48
|
+
/// maximum number of retry attempts.
|
|
49
|
+
pub max_retries: usize,
|
|
31
50
|
}
|
|
32
51
|
|
|
33
|
-
impl
|
|
34
|
-
|
|
35
|
-
pub fn new(client: SG, retry_config: RetryOptions) -> Self {
|
|
52
|
+
impl Default for RetryOptions {
|
|
53
|
+
fn default() -> Self {
|
|
36
54
|
Self {
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
initial_interval: Duration::from_millis(100), // 100 ms wait by default.
|
|
56
|
+
randomization_factor: 0.2, // +-20% jitter.
|
|
57
|
+
multiplier: 1.7, // each next retry delay will increase by 70%
|
|
58
|
+
max_interval: Duration::from_secs(5), // until it reaches 5 seconds.
|
|
59
|
+
max_elapsed_time: Some(Duration::from_secs(10)), // 10 seconds total allocated time for all retries.
|
|
60
|
+
max_retries: 10,
|
|
39
61
|
}
|
|
40
62
|
}
|
|
41
63
|
}
|
|
42
64
|
|
|
43
|
-
impl
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
65
|
+
impl RetryOptions {
|
|
66
|
+
pub(crate) const fn task_poll_retry_policy() -> Self {
|
|
67
|
+
Self {
|
|
68
|
+
initial_interval: Duration::from_millis(200),
|
|
69
|
+
randomization_factor: 0.2,
|
|
70
|
+
multiplier: 2.0,
|
|
71
|
+
max_interval: Duration::from_secs(10),
|
|
72
|
+
max_elapsed_time: None,
|
|
73
|
+
max_retries: 0,
|
|
74
|
+
}
|
|
47
75
|
}
|
|
48
76
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
77
|
+
pub(crate) const fn throttle_retry_policy() -> Self {
|
|
78
|
+
Self {
|
|
79
|
+
initial_interval: Duration::from_secs(1),
|
|
80
|
+
randomization_factor: 0.2,
|
|
81
|
+
multiplier: 2.0,
|
|
82
|
+
max_interval: Duration::from_secs(10),
|
|
83
|
+
max_elapsed_time: None,
|
|
84
|
+
max_retries: 0,
|
|
85
|
+
}
|
|
52
86
|
}
|
|
53
87
|
|
|
54
|
-
///
|
|
55
|
-
pub fn
|
|
56
|
-
|
|
88
|
+
/// A retry policy that never retires
|
|
89
|
+
pub const fn no_retries() -> Self {
|
|
90
|
+
Self {
|
|
91
|
+
initial_interval: Duration::from_secs(0),
|
|
92
|
+
randomization_factor: 0.0,
|
|
93
|
+
multiplier: 1.0,
|
|
94
|
+
max_interval: Duration::from_secs(0),
|
|
95
|
+
max_elapsed_time: None,
|
|
96
|
+
max_retries: 1,
|
|
97
|
+
}
|
|
57
98
|
}
|
|
58
99
|
|
|
59
100
|
pub(crate) fn get_call_info<R>(
|
|
60
101
|
&self,
|
|
61
102
|
call_name: &'static str,
|
|
62
|
-
request: Option<&Request<R>>,
|
|
103
|
+
request: Option<&tonic::Request<R>>,
|
|
63
104
|
) -> CallInfo {
|
|
64
105
|
let mut call_type = CallType::Normal;
|
|
65
106
|
let mut retry_short_circuit = None;
|
|
@@ -80,7 +121,7 @@ impl<SG> RetryClient<SG> {
|
|
|
80
121
|
} else if call_type == CallType::TaskLongPoll {
|
|
81
122
|
RetryOptions::task_poll_retry_policy()
|
|
82
123
|
} else {
|
|
83
|
-
|
|
124
|
+
self.clone()
|
|
84
125
|
};
|
|
85
126
|
CallInfo {
|
|
86
127
|
call_type,
|
|
@@ -90,32 +131,38 @@ impl<SG> RetryClient<SG> {
|
|
|
90
131
|
}
|
|
91
132
|
}
|
|
92
133
|
|
|
93
|
-
pub(crate) fn
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
)
|
|
134
|
+
pub(crate) fn into_exp_backoff<C>(self, clock: C) -> exponential::ExponentialBackoff<C> {
|
|
135
|
+
exponential::ExponentialBackoff {
|
|
136
|
+
current_interval: self.initial_interval,
|
|
137
|
+
initial_interval: self.initial_interval,
|
|
138
|
+
randomization_factor: self.randomization_factor,
|
|
139
|
+
multiplier: self.multiplier,
|
|
140
|
+
max_interval: self.max_interval,
|
|
141
|
+
max_elapsed_time: self.max_elapsed_time,
|
|
142
|
+
clock,
|
|
143
|
+
start_time: Instant::now(),
|
|
144
|
+
}
|
|
105
145
|
}
|
|
106
146
|
}
|
|
107
147
|
|
|
108
|
-
impl<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{
|
|
112
|
-
fn namespace(&self) -> String {
|
|
113
|
-
self.client.namespace()
|
|
148
|
+
impl From<RetryOptions> for backoff::ExponentialBackoff {
|
|
149
|
+
fn from(c: RetryOptions) -> Self {
|
|
150
|
+
c.into_exp_backoff(SystemClock::default())
|
|
114
151
|
}
|
|
152
|
+
}
|
|
115
153
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
154
|
+
pub(crate) fn make_future_retry<R, F, Fut>(
|
|
155
|
+
info: CallInfo,
|
|
156
|
+
factory: F,
|
|
157
|
+
) -> FutureRetry<F, TonicErrorHandler<SystemClock>>
|
|
158
|
+
where
|
|
159
|
+
F: FnMut() -> Fut + Unpin,
|
|
160
|
+
Fut: Future<Output = Result<R, tonic::Status>>,
|
|
161
|
+
{
|
|
162
|
+
FutureRetry::new(
|
|
163
|
+
factory,
|
|
164
|
+
TonicErrorHandler::new(info, RetryOptions::throttle_retry_policy()),
|
|
165
|
+
)
|
|
119
166
|
}
|
|
120
167
|
|
|
121
168
|
#[derive(Debug)]
|
|
@@ -525,12 +572,11 @@ mod tests {
|
|
|
525
572
|
) {
|
|
526
573
|
// A bit odd, but we don't need a real client to test the retry client passes through the
|
|
527
574
|
// correct retry config
|
|
528
|
-
let fake_retry = RetryClient::new((), TEST_RETRY_CONFIG);
|
|
529
575
|
let mut req = req.into_request();
|
|
530
576
|
req.extensions_mut().insert(IsWorkerTaskLongPoll);
|
|
531
577
|
for i in 1..=50 {
|
|
532
578
|
let mut err_handler = TonicErrorHandler::new(
|
|
533
|
-
|
|
579
|
+
TEST_RETRY_CONFIG.get_call_info::<R>(call_name, Some(&req)),
|
|
534
580
|
RetryOptions::throttle_retry_policy(),
|
|
535
581
|
);
|
|
536
582
|
let result = err_handler.handle(i, Status::new(Code::Unknown, "Ahh"));
|
|
@@ -557,13 +603,12 @@ mod tests {
|
|
|
557
603
|
)]
|
|
558
604
|
(call_name, req): (&'static str, R),
|
|
559
605
|
) {
|
|
560
|
-
let fake_retry = RetryClient::new((), TEST_RETRY_CONFIG);
|
|
561
606
|
let mut req = req.into_request();
|
|
562
607
|
req.extensions_mut().insert(IsWorkerTaskLongPoll);
|
|
563
608
|
// For some reason we will get cancelled in these situations occasionally (always?) too
|
|
564
609
|
for code in [Code::Cancelled, Code::DeadlineExceeded] {
|
|
565
610
|
let mut err_handler = TonicErrorHandler::new(
|
|
566
|
-
|
|
611
|
+
TEST_RETRY_CONFIG.get_call_info::<R>(call_name, Some(&req)),
|
|
567
612
|
RetryOptions::throttle_retry_policy(),
|
|
568
613
|
);
|
|
569
614
|
for i in 1..=5 {
|
|
@@ -213,28 +213,48 @@ impl ClientWorkerSetImpl {
|
|
|
213
213
|
Ok(())
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
.remove(&worker_instance_key)
|
|
223
|
-
.ok_or_else(|| {
|
|
224
|
-
anyhow::anyhow!("Worker with worker_instance_key {worker_instance_key} not found")
|
|
225
|
-
})?;
|
|
216
|
+
/// Slot provider should be unregistered at the beginning of worker shutdown, in order to disable
|
|
217
|
+
/// eager workflow start.
|
|
218
|
+
fn unregister_slot_provider(&mut self, worker_instance_key: Uuid) -> Result<(), anyhow::Error> {
|
|
219
|
+
let worker = self.all_workers.get(&worker_instance_key).ok_or_else(|| {
|
|
220
|
+
anyhow::anyhow!("Worker not in all_workers during slot provider unregister")
|
|
221
|
+
})?;
|
|
226
222
|
|
|
227
223
|
let slot_key = SlotKey::new(
|
|
228
224
|
worker.namespace().to_string(),
|
|
229
225
|
worker.task_queue().to_string(),
|
|
230
226
|
);
|
|
231
|
-
|
|
232
227
|
if let Some(slot_vec) = self.slot_providers.get_mut(&slot_key) {
|
|
233
228
|
slot_vec.retain(|info| info.worker_id != worker_instance_key);
|
|
234
229
|
if slot_vec.is_empty() {
|
|
235
230
|
self.slot_providers.remove(&slot_key);
|
|
236
231
|
}
|
|
237
232
|
}
|
|
233
|
+
Ok(())
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
fn finalize_unregister(
|
|
237
|
+
&mut self,
|
|
238
|
+
worker_instance_key: Uuid,
|
|
239
|
+
) -> Result<Arc<dyn ClientWorker + Send + Sync>, anyhow::Error> {
|
|
240
|
+
if let Some(worker) = self.all_workers.get(&worker_instance_key)
|
|
241
|
+
&& let Some(slot_vec) = self.slot_providers.get(&SlotKey::new(
|
|
242
|
+
worker.namespace().to_string(),
|
|
243
|
+
worker.task_queue().to_string(),
|
|
244
|
+
))
|
|
245
|
+
&& slot_vec
|
|
246
|
+
.iter()
|
|
247
|
+
.any(|info| info.worker_id == worker_instance_key)
|
|
248
|
+
{
|
|
249
|
+
return Err(anyhow::anyhow!(
|
|
250
|
+
"Worker still in slot_providers during finalize"
|
|
251
|
+
));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
let worker = self
|
|
255
|
+
.all_workers
|
|
256
|
+
.remove(&worker_instance_key)
|
|
257
|
+
.ok_or_else(|| anyhow::anyhow!("Worker not found in all_workers"))?;
|
|
238
258
|
|
|
239
259
|
if let Some(w) = self.shared_worker.get_mut(worker.namespace()) {
|
|
240
260
|
let (callback, is_empty) = w.unregister_callback(worker.worker_instance_key());
|
|
@@ -278,7 +298,7 @@ pub trait SharedNamespaceWorkerTrait {
|
|
|
278
298
|
/// Enables local workers to make themselves visible to a shared client instance.
|
|
279
299
|
///
|
|
280
300
|
/// For slot managing, there can only be one worker registered per
|
|
281
|
-
/// namespace+queue_name+
|
|
301
|
+
/// namespace+queue_name+connection, others will return an error.
|
|
282
302
|
/// It also provides a convenient method to find compatible slots within the collection.
|
|
283
303
|
pub struct ClientWorkerSet {
|
|
284
304
|
worker_grouping_key: Uuid,
|
|
@@ -323,12 +343,24 @@ impl ClientWorkerSet {
|
|
|
323
343
|
.register(worker, skip_client_worker_set_check)
|
|
324
344
|
}
|
|
325
345
|
|
|
326
|
-
///
|
|
327
|
-
|
|
346
|
+
/// Disables Eager Workflow Start for this worker. This must be called before
|
|
347
|
+
/// `finalize_unregister`, otherwise `finalize_unregister` will return an err.
|
|
348
|
+
pub fn unregister_slot_provider(&self, worker_instance_key: Uuid) -> Result<(), anyhow::Error> {
|
|
349
|
+
self.worker_manager
|
|
350
|
+
.write()
|
|
351
|
+
.unregister_slot_provider(worker_instance_key)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/// Finalizes unregistering of worker from client. This must be called at the end of worker
|
|
355
|
+
/// shutdown in order to finalize shutdown for worker heartbeat properly. Must call after
|
|
356
|
+
/// `unregister_slot_provider`, otherwise an err will be returned.
|
|
357
|
+
pub fn finalize_unregister(
|
|
328
358
|
&self,
|
|
329
359
|
worker_instance_key: Uuid,
|
|
330
360
|
) -> Result<Arc<dyn ClientWorker + Send + Sync>, anyhow::Error> {
|
|
331
|
-
self.worker_manager
|
|
361
|
+
self.worker_manager
|
|
362
|
+
.write()
|
|
363
|
+
.finalize_unregister(worker_instance_key)
|
|
332
364
|
}
|
|
333
365
|
|
|
334
366
|
/// Returns the worker grouping key, which is unique for each worker.
|
|
@@ -651,14 +683,14 @@ mod tests {
|
|
|
651
683
|
let worker_instance_key = mock_provider.worker_instance_key();
|
|
652
684
|
|
|
653
685
|
let result = manager.register_worker(Arc::new(mock_provider), false);
|
|
654
|
-
if
|
|
655
|
-
successful_registrations += 1;
|
|
656
|
-
worker_keys.push(worker_instance_key);
|
|
657
|
-
} else {
|
|
686
|
+
if let Err(err) = result {
|
|
658
687
|
// Should get error for overlapping worker task types
|
|
659
|
-
assert!(
|
|
688
|
+
assert!(err.to_string().contains(
|
|
660
689
|
"Registration of multiple workers with overlapping worker task types"
|
|
661
690
|
));
|
|
691
|
+
} else {
|
|
692
|
+
successful_registrations += 1;
|
|
693
|
+
worker_keys.push(worker_instance_key);
|
|
662
694
|
}
|
|
663
695
|
}
|
|
664
696
|
|
|
@@ -666,9 +698,12 @@ mod tests {
|
|
|
666
698
|
assert_eq!(3, manager.num_providers());
|
|
667
699
|
|
|
668
700
|
let count = worker_keys.iter().fold(0, |count, key| {
|
|
669
|
-
manager.
|
|
701
|
+
manager.unregister_slot_provider(*key).unwrap();
|
|
702
|
+
manager.finalize_unregister(*key).unwrap();
|
|
670
703
|
// expect error since worker is already unregistered
|
|
671
|
-
let result = manager.
|
|
704
|
+
let result = manager.unregister_slot_provider(*key);
|
|
705
|
+
assert!(result.is_err());
|
|
706
|
+
let result = manager.finalize_unregister(*key);
|
|
672
707
|
assert!(result.is_err());
|
|
673
708
|
count + 1
|
|
674
709
|
});
|
|
@@ -896,7 +931,10 @@ mod tests {
|
|
|
896
931
|
assert_eq!(providers[1].build_id, Some("build-1".to_string()));
|
|
897
932
|
}
|
|
898
933
|
|
|
899
|
-
manager
|
|
934
|
+
manager
|
|
935
|
+
.unregister_slot_provider(worker2_instance_key)
|
|
936
|
+
.unwrap();
|
|
937
|
+
manager.finalize_unregister(worker2_instance_key).unwrap();
|
|
900
938
|
|
|
901
939
|
{
|
|
902
940
|
let impl_ref = manager.worker_manager.read();
|
|
@@ -1016,7 +1054,10 @@ mod tests {
|
|
|
1016
1054
|
drop(impl_ref);
|
|
1017
1055
|
|
|
1018
1056
|
// Unregister first worker
|
|
1019
|
-
manager
|
|
1057
|
+
manager
|
|
1058
|
+
.unregister_slot_provider(worker_instance_key1)
|
|
1059
|
+
.unwrap();
|
|
1060
|
+
manager.finalize_unregister(worker_instance_key1).unwrap();
|
|
1020
1061
|
|
|
1021
1062
|
// After unregistering first worker: 1 slot provider, 1 heartbeat worker, shared worker still exists
|
|
1022
1063
|
assert_eq!(1, manager.num_providers());
|
|
@@ -1036,7 +1077,10 @@ mod tests {
|
|
|
1036
1077
|
drop(impl_ref);
|
|
1037
1078
|
|
|
1038
1079
|
// Unregister second worker
|
|
1039
|
-
manager
|
|
1080
|
+
manager
|
|
1081
|
+
.unregister_slot_provider(worker_instance_key2)
|
|
1082
|
+
.unwrap();
|
|
1083
|
+
manager.finalize_unregister(worker_instance_key2).unwrap();
|
|
1040
1084
|
|
|
1041
1085
|
// After unregistering last worker: 0 slot providers, 0 heartbeat workers, shared worker is removed
|
|
1042
1086
|
assert_eq!(0, manager.num_providers());
|
|
@@ -1447,8 +1491,11 @@ mod tests {
|
|
|
1447
1491
|
);
|
|
1448
1492
|
|
|
1449
1493
|
manager
|
|
1450
|
-
.
|
|
1451
|
-
.expect("should unregister workflow worker");
|
|
1494
|
+
.unregister_slot_provider(wf_worker_key)
|
|
1495
|
+
.expect("should unregister slot provider for workflow worker");
|
|
1496
|
+
manager
|
|
1497
|
+
.finalize_unregister(wf_worker_key)
|
|
1498
|
+
.expect("should finalize unregister for workflow worker");
|
|
1452
1499
|
|
|
1453
1500
|
// Activity worker should still be registered
|
|
1454
1501
|
assert_eq!(1, manager.num_providers());
|
|
@@ -1460,9 +1507,37 @@ mod tests {
|
|
|
1460
1507
|
);
|
|
1461
1508
|
|
|
1462
1509
|
manager
|
|
1463
|
-
.
|
|
1464
|
-
.expect("should unregister activity worker");
|
|
1510
|
+
.unregister_slot_provider(act_worker_key)
|
|
1511
|
+
.expect("should unregister slot provider for activity worker");
|
|
1512
|
+
manager
|
|
1513
|
+
.finalize_unregister(act_worker_key)
|
|
1514
|
+
.expect("should finalize unregister for activity worker");
|
|
1465
1515
|
|
|
1466
1516
|
assert_eq!(0, manager.num_providers());
|
|
1467
1517
|
}
|
|
1518
|
+
|
|
1519
|
+
#[test]
|
|
1520
|
+
fn worker_unregister_order() {
|
|
1521
|
+
let manager = ClientWorkerSet::new();
|
|
1522
|
+
let worker = new_mock_provider_with_heartbeat(
|
|
1523
|
+
"namespace1".to_string(),
|
|
1524
|
+
"queue1".to_string(),
|
|
1525
|
+
true,
|
|
1526
|
+
None,
|
|
1527
|
+
);
|
|
1528
|
+
let worker_instance_key = worker.worker_instance_key();
|
|
1529
|
+
manager.register_worker(Arc::new(worker), false).unwrap();
|
|
1530
|
+
|
|
1531
|
+
let res = manager.finalize_unregister(worker_instance_key);
|
|
1532
|
+
assert!(res.is_err());
|
|
1533
|
+
let err_string = res.err().map(|e| e.to_string()).unwrap();
|
|
1534
|
+
assert!(err_string.contains("Worker still in slot_providers during finalize"));
|
|
1535
|
+
|
|
1536
|
+
// previous incorrect call to finalize_unregister should not cause any state leaks when
|
|
1537
|
+
// properly removed later
|
|
1538
|
+
manager
|
|
1539
|
+
.unregister_slot_provider(worker_instance_key)
|
|
1540
|
+
.unwrap();
|
|
1541
|
+
manager.finalize_unregister(worker_instance_key).unwrap();
|
|
1542
|
+
}
|
|
1468
1543
|
}
|