@temporalio/core-bridge 0.16.4 → 0.18.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 +339 -226
- package/Cargo.toml +7 -3
- package/common.js +50 -0
- package/index.d.ts +7 -0
- package/index.js +12 -0
- package/package.json +7 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/{index.node → releases/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 +10 -50
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/Cargo.toml +1 -88
- package/sdk-core/README.md +30 -6
- package/sdk-core/bridge-ffi/Cargo.toml +24 -0
- package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- package/sdk-core/bridge-ffi/build.rs +25 -0
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
- package/sdk-core/bridge-ffi/src/lib.rs +829 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
- package/sdk-core/client/Cargo.toml +32 -0
- package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
- package/sdk-core/client/src/metrics.rs +89 -0
- package/sdk-core/client/src/mocks.rs +167 -0
- package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
- package/sdk-core/core/Cargo.toml +96 -0
- package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
- package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
- package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
- package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
- package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
- package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
- package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
- package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
- package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
- package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
- package/sdk-core/core/src/lib.rs +374 -0
- package/sdk-core/{src → core/src}/log_export.rs +3 -27
- package/sdk-core/core/src/pending_activations.rs +162 -0
- package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
- package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
- package/sdk-core/core/src/protosext/mod.rs +396 -0
- package/sdk-core/core/src/replay/mod.rs +210 -0
- package/sdk-core/core/src/retry_logic.rs +144 -0
- package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
- package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
- package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
- package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
- package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
- package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
- package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
- package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
- package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
- package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
- package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
- package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
- package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
- package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
- package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
- package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
- package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
- package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
- package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
- package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
- package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
- package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
- package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
- package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
- package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
- package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
- package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
- package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
- package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
- package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
- package/sdk-core/{src → core-api/src}/errors.rs +42 -92
- package/sdk-core/core-api/src/lib.rs +158 -0
- package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
- package/sdk-core/etc/deps.svg +156 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
- package/sdk-core/histories/fail_wf_task.bin +0 -0
- package/sdk-core/histories/timer_workflow_history.bin +0 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
- package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
- package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
- package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
- package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
- package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
- package/sdk-core/sdk/Cargo.toml +32 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
- package/sdk-core/sdk/src/lib.rs +699 -0
- package/sdk-core/sdk/src/payload_converter.rs +11 -0
- package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
- package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
- package/sdk-core/sdk-core-protos/build.rs +28 -6
- package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
- package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
- package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +32 -0
- package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
- package/sdk-core/test-utils/src/histfetch.rs +28 -0
- package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
- package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
- package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
- package/sdk-core/tests/load_tests.rs +6 -6
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +24 -21
- package/src/errors.rs +8 -0
- package/src/lib.rs +323 -211
- package/sdk-core/protos/local/activity_result.proto +0 -46
- package/sdk-core/protos/local/activity_task.proto +0 -66
- package/sdk-core/src/core_tests/retry.rs +0 -147
- package/sdk-core/src/lib.rs +0 -403
- package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
- package/sdk-core/src/pending_activations.rs +0 -249
- package/sdk-core/src/protosext/mod.rs +0 -160
- package/sdk-core/src/prototype_rust_sdk.rs +0 -412
- package/sdk-core/src/task_token.rs +0 -20
- package/sdk-core/src/test_help/history_info.rs +0 -157
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
|
|
3
|
-
package coresdk.activity_result;
|
|
4
|
-
|
|
5
|
-
import "common.proto";
|
|
6
|
-
import "temporal/api/failure/v1/message.proto";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Used to report activity completion to core and to resolve the activity in a workflow activation
|
|
10
|
-
*/
|
|
11
|
-
message ActivityResult {
|
|
12
|
-
oneof status {
|
|
13
|
-
Success completed = 1;
|
|
14
|
-
Failure failed = 2;
|
|
15
|
-
Cancellation cancelled = 3;
|
|
16
|
-
WillCompleteAsync will_complete_async = 4;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Used in ActivityResult to report successful completion */
|
|
21
|
-
message Success {
|
|
22
|
-
common.Payload result = 1;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** Used in ActivityResult to report failure */
|
|
26
|
-
message Failure {
|
|
27
|
-
temporal.api.failure.v1.Failure failure = 1;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Used in ActivityResult to report cancellation from both Core and Lang.
|
|
32
|
-
* When Lang reports a cancelled ActivityResult, it must put a CancelledFailure in the failure field.
|
|
33
|
-
* When Core reports a cancelled ActivityResult, it must put an ActivityFailure with CancelledFailure
|
|
34
|
-
* as the cause in the failure field.
|
|
35
|
-
*/
|
|
36
|
-
message Cancellation {
|
|
37
|
-
temporal.api.failure.v1.Failure failure = 1;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Used in ActivityResult to notify Core that this Activity will complete asynchronously.
|
|
42
|
-
* Core will forget about this Activity and free up resources used to track this Activity.
|
|
43
|
-
*/
|
|
44
|
-
message WillCompleteAsync {
|
|
45
|
-
}
|
|
46
|
-
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
syntax = "proto3";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Definitions of the different activity tasks returned from [crate::Core::poll_task].
|
|
5
|
-
*/
|
|
6
|
-
package coresdk.activity_task;
|
|
7
|
-
|
|
8
|
-
import "common.proto";
|
|
9
|
-
|
|
10
|
-
import "google/protobuf/timestamp.proto";
|
|
11
|
-
import "google/protobuf/duration.proto";
|
|
12
|
-
|
|
13
|
-
message ActivityTask {
|
|
14
|
-
/// A unique identifier for this task
|
|
15
|
-
bytes task_token = 1;
|
|
16
|
-
/// The activity's ID
|
|
17
|
-
string activity_id = 2;
|
|
18
|
-
oneof variant {
|
|
19
|
-
/// Start activity execution.
|
|
20
|
-
Start start = 3;
|
|
21
|
-
/// Attempt to cancel activity execution.
|
|
22
|
-
Cancel cancel = 4;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/// Begin executing an activity
|
|
27
|
-
message Start {
|
|
28
|
-
/// The namespace the workflow lives in
|
|
29
|
-
string workflow_namespace = 1;
|
|
30
|
-
/// The workflow's type name or function identifier
|
|
31
|
-
string workflow_type = 2;
|
|
32
|
-
common.WorkflowExecution workflow_execution = 3;
|
|
33
|
-
/// The activity's type name or function identifier
|
|
34
|
-
string activity_type = 4;
|
|
35
|
-
map<string, common.Payload> header_fields = 5;
|
|
36
|
-
/// Arguments to the activity
|
|
37
|
-
repeated common.Payload input = 6;
|
|
38
|
-
repeated common.Payload heartbeat_details = 7;
|
|
39
|
-
|
|
40
|
-
google.protobuf.Timestamp scheduled_time = 8;
|
|
41
|
-
google.protobuf.Timestamp current_attempt_scheduled_time = 9;
|
|
42
|
-
google.protobuf.Timestamp started_time = 10;
|
|
43
|
-
int32 attempt = 11;
|
|
44
|
-
|
|
45
|
-
google.protobuf.Duration schedule_to_close_timeout = 12;
|
|
46
|
-
google.protobuf.Duration start_to_close_timeout = 13;
|
|
47
|
-
google.protobuf.Duration heartbeat_timeout = 14;
|
|
48
|
-
/// This is an actual retry policy the service uses. It can be different from the one provided
|
|
49
|
-
/// (or not) during activity scheduling as the service can override the provided one in case its
|
|
50
|
-
/// values are not specified or exceed configured system limits.
|
|
51
|
-
common.RetryPolicy retry_policy = 15;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/// Attempt to cancel a running activity
|
|
55
|
-
message Cancel {
|
|
56
|
-
ActivityCancelReason reason = 1;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
enum ActivityCancelReason {
|
|
60
|
-
/// The activity no longer exists according to server (may be already completed)
|
|
61
|
-
NOT_FOUND = 0;
|
|
62
|
-
/// Activity was explicitly cancelled
|
|
63
|
-
CANCELLED = 1;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
use crate::{
|
|
2
|
-
pollers::{MockServerGatewayApis, RetryGateway, RETRYABLE_ERROR_CODES},
|
|
3
|
-
ServerGatewayApis,
|
|
4
|
-
};
|
|
5
|
-
use tonic::{Code, Status};
|
|
6
|
-
|
|
7
|
-
#[tokio::test]
|
|
8
|
-
async fn non_retryable_errors() {
|
|
9
|
-
for code in [
|
|
10
|
-
Code::InvalidArgument,
|
|
11
|
-
Code::NotFound,
|
|
12
|
-
Code::AlreadyExists,
|
|
13
|
-
Code::PermissionDenied,
|
|
14
|
-
Code::FailedPrecondition,
|
|
15
|
-
Code::Cancelled,
|
|
16
|
-
Code::DeadlineExceeded,
|
|
17
|
-
Code::Unauthenticated,
|
|
18
|
-
Code::Unimplemented,
|
|
19
|
-
] {
|
|
20
|
-
let mut mock_gateway = MockServerGatewayApis::new();
|
|
21
|
-
mock_gateway
|
|
22
|
-
.expect_cancel_activity_task()
|
|
23
|
-
.returning(move |_, _| Err(Status::new(code, "non-retryable failure")))
|
|
24
|
-
.times(1);
|
|
25
|
-
let retry_gateway = RetryGateway::new(mock_gateway, Default::default());
|
|
26
|
-
let result = retry_gateway
|
|
27
|
-
.cancel_activity_task(vec![1].into(), None)
|
|
28
|
-
.await;
|
|
29
|
-
// Expecting an error after a single attempt, since there was a non-retryable error.
|
|
30
|
-
assert!(result.is_err());
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
#[tokio::test]
|
|
35
|
-
async fn long_poll_non_retryable_errors() {
|
|
36
|
-
for code in [
|
|
37
|
-
Code::InvalidArgument,
|
|
38
|
-
Code::NotFound,
|
|
39
|
-
Code::AlreadyExists,
|
|
40
|
-
Code::PermissionDenied,
|
|
41
|
-
Code::FailedPrecondition,
|
|
42
|
-
Code::Unauthenticated,
|
|
43
|
-
Code::Unimplemented,
|
|
44
|
-
] {
|
|
45
|
-
let mut mock_gateway = MockServerGatewayApis::new();
|
|
46
|
-
mock_gateway
|
|
47
|
-
.expect_poll_workflow_task()
|
|
48
|
-
.returning(move |_, _| Err(Status::new(code, "non-retryable failure")))
|
|
49
|
-
.times(1);
|
|
50
|
-
mock_gateway
|
|
51
|
-
.expect_poll_activity_task()
|
|
52
|
-
.returning(move |_| Err(Status::new(code, "non-retryable failure")))
|
|
53
|
-
.times(1);
|
|
54
|
-
let retry_gateway = RetryGateway::new(mock_gateway, Default::default());
|
|
55
|
-
let result = retry_gateway
|
|
56
|
-
.poll_workflow_task("tq".to_string(), false)
|
|
57
|
-
.await;
|
|
58
|
-
assert!(result.is_err());
|
|
59
|
-
let result = retry_gateway.poll_activity_task("tq".to_string()).await;
|
|
60
|
-
assert!(result.is_err());
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
#[tokio::test]
|
|
65
|
-
async fn retryable_errors() {
|
|
66
|
-
for code in RETRYABLE_ERROR_CODES {
|
|
67
|
-
let mut mock_gateway = MockServerGatewayApis::new();
|
|
68
|
-
mock_gateway
|
|
69
|
-
.expect_cancel_activity_task()
|
|
70
|
-
.returning(move |_, _| Err(Status::new(code, "retryable failure")))
|
|
71
|
-
.times(3);
|
|
72
|
-
mock_gateway
|
|
73
|
-
.expect_cancel_activity_task()
|
|
74
|
-
.returning(|_, _| Ok(Default::default()))
|
|
75
|
-
.times(1);
|
|
76
|
-
|
|
77
|
-
let retry_gateway = RetryGateway::new(mock_gateway, Default::default());
|
|
78
|
-
let result = retry_gateway
|
|
79
|
-
.cancel_activity_task(vec![1].into(), None)
|
|
80
|
-
.await;
|
|
81
|
-
// Expecting successful response after retries
|
|
82
|
-
assert!(result.is_ok());
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
#[tokio::test]
|
|
87
|
-
async fn long_poll_retries_forever() {
|
|
88
|
-
let mut mock_gateway = MockServerGatewayApis::new();
|
|
89
|
-
mock_gateway
|
|
90
|
-
.expect_poll_workflow_task()
|
|
91
|
-
.returning(move |_, _| Err(Status::new(Code::Unknown, "retryable failure")))
|
|
92
|
-
.times(50);
|
|
93
|
-
mock_gateway
|
|
94
|
-
.expect_poll_workflow_task()
|
|
95
|
-
.returning(|_, _| Ok(Default::default()))
|
|
96
|
-
.times(1);
|
|
97
|
-
mock_gateway
|
|
98
|
-
.expect_poll_activity_task()
|
|
99
|
-
.returning(move |_| Err(Status::new(Code::Unknown, "retryable failure")))
|
|
100
|
-
.times(50);
|
|
101
|
-
mock_gateway
|
|
102
|
-
.expect_poll_activity_task()
|
|
103
|
-
.returning(|_| Ok(Default::default()))
|
|
104
|
-
.times(1);
|
|
105
|
-
|
|
106
|
-
let retry_gateway = RetryGateway::new(mock_gateway, Default::default());
|
|
107
|
-
|
|
108
|
-
let result = retry_gateway
|
|
109
|
-
.poll_workflow_task("tq".to_string(), false)
|
|
110
|
-
.await;
|
|
111
|
-
assert!(result.is_ok());
|
|
112
|
-
let result = retry_gateway.poll_activity_task("tq".to_string()).await;
|
|
113
|
-
assert!(result.is_ok());
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
#[tokio::test]
|
|
117
|
-
async fn long_poll_retries_deadline_exceeded() {
|
|
118
|
-
// For some reason we will get cancelled in these situations occasionally (always?) too
|
|
119
|
-
for code in [Code::Cancelled, Code::DeadlineExceeded] {
|
|
120
|
-
let mut mock_gateway = MockServerGatewayApis::new();
|
|
121
|
-
mock_gateway
|
|
122
|
-
.expect_poll_workflow_task()
|
|
123
|
-
.returning(move |_, _| Err(Status::new(code, "retryable failure")))
|
|
124
|
-
.times(5);
|
|
125
|
-
mock_gateway
|
|
126
|
-
.expect_poll_workflow_task()
|
|
127
|
-
.returning(|_, _| Ok(Default::default()))
|
|
128
|
-
.times(1);
|
|
129
|
-
mock_gateway
|
|
130
|
-
.expect_poll_activity_task()
|
|
131
|
-
.returning(move |_| Err(Status::new(code, "retryable failure")))
|
|
132
|
-
.times(5);
|
|
133
|
-
mock_gateway
|
|
134
|
-
.expect_poll_activity_task()
|
|
135
|
-
.returning(|_| Ok(Default::default()))
|
|
136
|
-
.times(1);
|
|
137
|
-
|
|
138
|
-
let retry_gateway = RetryGateway::new(mock_gateway, Default::default());
|
|
139
|
-
|
|
140
|
-
let result = retry_gateway
|
|
141
|
-
.poll_workflow_task("tq".to_string(), false)
|
|
142
|
-
.await;
|
|
143
|
-
assert!(result.is_ok());
|
|
144
|
-
let result = retry_gateway.poll_activity_task("tq".to_string()).await;
|
|
145
|
-
assert!(result.is_ok());
|
|
146
|
-
}
|
|
147
|
-
}
|
package/sdk-core/src/lib.rs
DELETED
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
#![warn(missing_docs)] // error if there are missing docs
|
|
2
|
-
#![allow(clippy::upper_case_acronyms)]
|
|
3
|
-
|
|
4
|
-
//! This crate provides a basis for creating new Temporal SDKs without completely starting from
|
|
5
|
-
//! scratch
|
|
6
|
-
|
|
7
|
-
#[cfg(test)]
|
|
8
|
-
#[macro_use]
|
|
9
|
-
pub extern crate assert_matches;
|
|
10
|
-
#[macro_use]
|
|
11
|
-
extern crate tracing;
|
|
12
|
-
|
|
13
|
-
pub mod errors;
|
|
14
|
-
pub mod prototype_rust_sdk;
|
|
15
|
-
|
|
16
|
-
mod log_export;
|
|
17
|
-
mod machines;
|
|
18
|
-
mod pending_activations;
|
|
19
|
-
mod pollers;
|
|
20
|
-
mod protosext;
|
|
21
|
-
pub(crate) mod task_token;
|
|
22
|
-
pub(crate) mod telemetry;
|
|
23
|
-
mod worker;
|
|
24
|
-
mod workflow;
|
|
25
|
-
|
|
26
|
-
#[cfg(test)]
|
|
27
|
-
mod core_tests;
|
|
28
|
-
#[cfg(test)]
|
|
29
|
-
#[macro_use]
|
|
30
|
-
mod test_help;
|
|
31
|
-
|
|
32
|
-
pub use log_export::CoreLog;
|
|
33
|
-
pub use pollers::{
|
|
34
|
-
ClientTlsConfig, RetryConfig, RetryGateway, ServerGateway, ServerGatewayApis,
|
|
35
|
-
ServerGatewayOptions, ServerGatewayOptionsBuilder, TlsConfig,
|
|
36
|
-
};
|
|
37
|
-
pub use telemetry::{TelemetryOptions, TelemetryOptionsBuilder};
|
|
38
|
-
pub use url::Url;
|
|
39
|
-
pub use worker::{WorkerConfig, WorkerConfigBuilder};
|
|
40
|
-
|
|
41
|
-
use crate::{
|
|
42
|
-
errors::{
|
|
43
|
-
ActivityHeartbeatError, CompleteActivityError, CompleteWfError, CoreInitError,
|
|
44
|
-
PollActivityError, PollWfError, WorkerRegistrationError,
|
|
45
|
-
},
|
|
46
|
-
pollers::GatewayRef,
|
|
47
|
-
task_token::TaskToken,
|
|
48
|
-
telemetry::{fetch_global_buffered_logs, telemetry_init},
|
|
49
|
-
worker::{Worker, WorkerDispatcher},
|
|
50
|
-
};
|
|
51
|
-
use std::{
|
|
52
|
-
ops::Deref,
|
|
53
|
-
sync::{
|
|
54
|
-
atomic::{AtomicBool, Ordering},
|
|
55
|
-
Arc,
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
use temporal_sdk_core_protos::coresdk::{
|
|
59
|
-
activity_task::ActivityTask, workflow_activation::WfActivation,
|
|
60
|
-
workflow_completion::WfActivationCompletion, ActivityHeartbeat, ActivityTaskCompletion,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
use crate::telemetry::metrics::MetricsContext;
|
|
64
|
-
#[cfg(test)]
|
|
65
|
-
use crate::test_help::MockWorker;
|
|
66
|
-
|
|
67
|
-
lazy_static::lazy_static! {
|
|
68
|
-
/// A process-wide unique string, which will be different on every startup
|
|
69
|
-
static ref PROCCESS_UNIQ_ID: String = {
|
|
70
|
-
uuid::Uuid::new_v4().to_simple().to_string()
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/// This trait is the primary way by which language specific SDKs interact with the core SDK. It is
|
|
75
|
-
/// expected that only one instance of an implementation will exist for the lifetime of the
|
|
76
|
-
/// worker(s) using it.
|
|
77
|
-
#[async_trait::async_trait]
|
|
78
|
-
pub trait Core: Send + Sync {
|
|
79
|
-
/// Register a worker with core. Workers poll on a specific task queue, and when calling core's
|
|
80
|
-
/// poll functions, you must provide a task queue name. If there was already a worker registered
|
|
81
|
-
/// with the same task queue name, it will be shut down and a new one will be created.
|
|
82
|
-
async fn register_worker(&self, config: WorkerConfig) -> Result<(), WorkerRegistrationError>;
|
|
83
|
-
|
|
84
|
-
/// Ask the core for some work, returning a [WfActivation]. It is then the language SDK's
|
|
85
|
-
/// responsibility to call the appropriate workflow code with the provided inputs. Blocks
|
|
86
|
-
/// indefinitely until such work is available or [Core::shutdown] is called.
|
|
87
|
-
///
|
|
88
|
-
/// The returned activation is guaranteed to be for the same task queue / worker which was
|
|
89
|
-
/// provided as the `task_queue` argument.
|
|
90
|
-
///
|
|
91
|
-
/// It is important to understand that all activations must be responded to. There can only
|
|
92
|
-
/// be one outstanding activation for a particular run of a workflow at any time. If an
|
|
93
|
-
/// activation is not responded to, it will cause that workflow to become stuck forever.
|
|
94
|
-
///
|
|
95
|
-
/// Activations that contain only a `remove_from_cache` job should not cause the workflow code
|
|
96
|
-
/// to be invoked and may be responded to with an empty command list. Eviction jobs may also
|
|
97
|
-
/// appear with other jobs, but will always appear last in the job list. In this case it is
|
|
98
|
-
/// expected that the workflow code will be invoked, and the response produced as normal, but
|
|
99
|
-
/// the caller should evict the run after doing so.
|
|
100
|
-
///
|
|
101
|
-
/// It is rarely a good idea to call poll concurrently. It handles polling the server
|
|
102
|
-
/// concurrently internally.
|
|
103
|
-
///
|
|
104
|
-
/// TODO: Examples
|
|
105
|
-
async fn poll_workflow_activation(&self, task_queue: &str)
|
|
106
|
-
-> Result<WfActivation, PollWfError>;
|
|
107
|
-
|
|
108
|
-
/// Ask the core for some work, returning an [ActivityTask]. It is then the language SDK's
|
|
109
|
-
/// responsibility to call the appropriate activity code with the provided inputs. Blocks
|
|
110
|
-
/// indefinitely until such work is available or [Core::shutdown] is called.
|
|
111
|
-
///
|
|
112
|
-
/// The returned activation is guaranteed to be for the same task queue / worker which was
|
|
113
|
-
/// provided as the `task_queue` argument.
|
|
114
|
-
///
|
|
115
|
-
/// It is rarely a good idea to call poll concurrently. It handles polling the server
|
|
116
|
-
/// concurrently internally.
|
|
117
|
-
///
|
|
118
|
-
/// TODO: Examples
|
|
119
|
-
async fn poll_activity_task(&self, task_queue: &str)
|
|
120
|
-
-> Result<ActivityTask, PollActivityError>;
|
|
121
|
-
|
|
122
|
-
/// Tell the core that a workflow activation has completed. May be freely called concurrently.
|
|
123
|
-
async fn complete_workflow_activation(
|
|
124
|
-
&self,
|
|
125
|
-
completion: WfActivationCompletion,
|
|
126
|
-
) -> Result<(), CompleteWfError>;
|
|
127
|
-
|
|
128
|
-
/// Tell the core that an activity has finished executing. May be freely called concurrently.
|
|
129
|
-
async fn complete_activity_task(
|
|
130
|
-
&self,
|
|
131
|
-
completion: ActivityTaskCompletion,
|
|
132
|
-
) -> Result<(), CompleteActivityError>;
|
|
133
|
-
|
|
134
|
-
/// Notify workflow that an activity is still alive. Long running activities that take longer
|
|
135
|
-
/// than `activity_heartbeat_timeout` to finish must call this function in order to report
|
|
136
|
-
/// progress, otherwise the activity will timeout and a new attempt will be scheduled.
|
|
137
|
-
///
|
|
138
|
-
/// The first heartbeat request will be sent immediately, subsequent rapid calls to this
|
|
139
|
-
/// function will result in heartbeat requests being aggregated and the last one received during
|
|
140
|
-
/// the aggregation period will be sent to the server, where that period is defined as half the
|
|
141
|
-
/// heartbeat timeout.
|
|
142
|
-
///
|
|
143
|
-
/// Unlike java/go SDKs we do not return cancellation status as part of heartbeat response and
|
|
144
|
-
/// instead send it as a separate activity task to the lang, decoupling heartbeat and
|
|
145
|
-
/// cancellation processing.
|
|
146
|
-
///
|
|
147
|
-
/// For now activity still need to send heartbeats if they want to receive cancellation
|
|
148
|
-
/// requests. In the future we will change this and will dispatch cancellations more
|
|
149
|
-
/// proactively. Note that this function does not block on the server call and returns
|
|
150
|
-
/// immediately. Underlying validation errors are swallowed and logged, this has been agreed to
|
|
151
|
-
/// be optimal behavior for the user as we don't want to break activity execution due to badly
|
|
152
|
-
/// configured heartbeat options.
|
|
153
|
-
fn record_activity_heartbeat(&self, details: ActivityHeartbeat);
|
|
154
|
-
|
|
155
|
-
/// Request that a workflow be evicted by its run id. This will generate a workflow activation
|
|
156
|
-
/// with the eviction job inside it to be eventually returned by
|
|
157
|
-
/// [Core::poll_workflow_activation]. If the workflow had any existing outstanding activations,
|
|
158
|
-
/// such activations are invalidated and subsequent completions of them will do nothing and log
|
|
159
|
-
/// a warning.
|
|
160
|
-
fn request_workflow_eviction(&self, task_queue: &str, run_id: &str);
|
|
161
|
-
|
|
162
|
-
/// Returns core's instance of the [ServerGatewayApis] implementor it is using.
|
|
163
|
-
fn server_gateway(&self) -> Arc<dyn ServerGatewayApis + Send + Sync>;
|
|
164
|
-
|
|
165
|
-
/// Initiates async shutdown procedure, eventually ceases all polling of the server and shuts
|
|
166
|
-
/// down all registered workers. [Core::poll_workflow_activation] should be called until it
|
|
167
|
-
/// returns [PollWfError::ShutDown] to ensure that any workflows which are still undergoing
|
|
168
|
-
/// replay have an opportunity to finish. This means that the lang sdk will need to call
|
|
169
|
-
/// [Core::complete_workflow_activation] for those workflows until they are done. At that point,
|
|
170
|
-
/// the lang SDK can end the process, or drop the [Core] instance, which will close the
|
|
171
|
-
/// connection.
|
|
172
|
-
async fn shutdown(&self);
|
|
173
|
-
|
|
174
|
-
/// Shut down a specific worker. Will cease all polling on the task queue and future attempts
|
|
175
|
-
/// to poll that queue will return [PollWfError::NoWorkerForQueue].
|
|
176
|
-
async fn shutdown_worker(&self, task_queue: &str);
|
|
177
|
-
|
|
178
|
-
/// Retrieve options that were passed in when initializing core
|
|
179
|
-
fn get_init_options(&self) -> &CoreInitOptions;
|
|
180
|
-
|
|
181
|
-
/// Core buffers logs that should be shuttled over to lang so that they may be rendered with
|
|
182
|
-
/// the user's desired logging library. Use this function to grab the most recent buffered logs
|
|
183
|
-
/// since the last time it was called. A fixed number of such logs are retained at maximum, with
|
|
184
|
-
/// the oldest being dropped when full.
|
|
185
|
-
///
|
|
186
|
-
/// Returns the list of logs from oldest to newest. Returns an empty vec if the feature is not
|
|
187
|
-
/// configured.
|
|
188
|
-
fn fetch_buffered_logs(&self) -> Vec<CoreLog>;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/// Holds various configuration information required to call [init]
|
|
192
|
-
#[derive(Debug, Clone, derive_builder::Builder)]
|
|
193
|
-
#[builder(setter(into))]
|
|
194
|
-
#[non_exhaustive]
|
|
195
|
-
pub struct CoreInitOptions {
|
|
196
|
-
/// Options for the connection to the temporal server
|
|
197
|
-
pub gateway_opts: ServerGatewayOptions,
|
|
198
|
-
/// Options for telemetry (traces and metrics)
|
|
199
|
-
#[builder(default)]
|
|
200
|
-
pub telemetry_opts: TelemetryOptions,
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/// Initializes an instance of the core sdk and establishes a connection to the temporal server.
|
|
204
|
-
///
|
|
205
|
-
/// Note: Also creates a tokio runtime that will be used for all client-server interactions.
|
|
206
|
-
///
|
|
207
|
-
/// # Panics
|
|
208
|
-
/// * Will panic if called from within an async context, as it will construct a runtime and you
|
|
209
|
-
/// cannot construct a runtime from within a runtime.
|
|
210
|
-
pub async fn init(opts: CoreInitOptions) -> Result<impl Core, CoreInitError> {
|
|
211
|
-
telemetry_init(&opts.telemetry_opts).map_err(CoreInitError::TelemetryInitError)?;
|
|
212
|
-
// Initialize server client
|
|
213
|
-
let server_gateway = opts.gateway_opts.connect().await?;
|
|
214
|
-
|
|
215
|
-
Ok(CoreSDK::new(server_gateway, opts))
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
struct CoreSDK {
|
|
219
|
-
/// Options provided at initialization time
|
|
220
|
-
init_options: CoreInitOptions,
|
|
221
|
-
/// Provides work in the form of responses the server would send from polling task Qs
|
|
222
|
-
server_gateway: Arc<GatewayRef>,
|
|
223
|
-
/// Controls access to workers
|
|
224
|
-
workers: WorkerDispatcher,
|
|
225
|
-
/// Has shutdown been called?
|
|
226
|
-
shutdown_requested: AtomicBool,
|
|
227
|
-
/// Top-level metrics context
|
|
228
|
-
metrics: MetricsContext,
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
#[async_trait::async_trait]
|
|
232
|
-
impl Core for CoreSDK {
|
|
233
|
-
async fn register_worker(&self, config: WorkerConfig) -> Result<(), WorkerRegistrationError> {
|
|
234
|
-
info!(
|
|
235
|
-
task_queue = config.task_queue.as_str(),
|
|
236
|
-
"Registering worker"
|
|
237
|
-
);
|
|
238
|
-
let sticky_q = self.get_sticky_q_name_for_worker(&config);
|
|
239
|
-
self.workers
|
|
240
|
-
.new_worker(
|
|
241
|
-
config,
|
|
242
|
-
sticky_q,
|
|
243
|
-
self.server_gateway.clone(),
|
|
244
|
-
self.metrics.clone(),
|
|
245
|
-
)
|
|
246
|
-
.await
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
#[instrument(level = "debug", skip(self), fields(run_id))]
|
|
250
|
-
async fn poll_workflow_activation(
|
|
251
|
-
&self,
|
|
252
|
-
task_queue: &str,
|
|
253
|
-
) -> Result<WfActivation, PollWfError> {
|
|
254
|
-
let worker = self.worker(task_queue)?;
|
|
255
|
-
worker.next_workflow_activation().await
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
#[instrument(level = "debug", skip(self))]
|
|
259
|
-
async fn poll_activity_task(
|
|
260
|
-
&self,
|
|
261
|
-
task_queue: &str,
|
|
262
|
-
) -> Result<ActivityTask, PollActivityError> {
|
|
263
|
-
loop {
|
|
264
|
-
if self.shutdown_requested.load(Ordering::Relaxed) {
|
|
265
|
-
return Err(PollActivityError::ShutDown);
|
|
266
|
-
}
|
|
267
|
-
let worker = self.worker(task_queue)?;
|
|
268
|
-
match worker.activity_poll().await.transpose() {
|
|
269
|
-
Some(r) => break r,
|
|
270
|
-
None => continue,
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
#[instrument(level = "debug", skip(self, completion),
|
|
276
|
-
fields(completion=%&completion, run_id=%completion.run_id))]
|
|
277
|
-
async fn complete_workflow_activation(
|
|
278
|
-
&self,
|
|
279
|
-
completion: WfActivationCompletion,
|
|
280
|
-
) -> Result<(), CompleteWfError> {
|
|
281
|
-
let worker = self.worker(&completion.task_queue)?;
|
|
282
|
-
worker.complete_workflow_activation(completion).await
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
#[instrument(level = "debug", skip(self))]
|
|
286
|
-
async fn complete_activity_task(
|
|
287
|
-
&self,
|
|
288
|
-
completion: ActivityTaskCompletion,
|
|
289
|
-
) -> Result<(), CompleteActivityError> {
|
|
290
|
-
let task_token = TaskToken(completion.task_token);
|
|
291
|
-
let status = if let Some(s) = completion.result.and_then(|r| r.status) {
|
|
292
|
-
s
|
|
293
|
-
} else {
|
|
294
|
-
return Err(CompleteActivityError::MalformedActivityCompletion {
|
|
295
|
-
reason: "Activity completion had empty result/status field".to_owned(),
|
|
296
|
-
completion: None,
|
|
297
|
-
});
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
let worker = self.worker(&completion.task_queue)?;
|
|
301
|
-
worker.complete_activity(task_token, status).await
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
fn record_activity_heartbeat(&self, details: ActivityHeartbeat) {
|
|
305
|
-
if let Ok(w) = self.worker(&details.task_queue) {
|
|
306
|
-
w.record_heartbeat(details);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
fn request_workflow_eviction(&self, task_queue: &str, run_id: &str) {
|
|
311
|
-
if let Ok(w) = self.worker(task_queue) {
|
|
312
|
-
w.request_wf_eviction(run_id, "Eviction explicitly requested by lang");
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
fn server_gateway(&self) -> Arc<dyn ServerGatewayApis + Send + Sync> {
|
|
317
|
-
self.server_gateway.gw.clone()
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
async fn shutdown(&self) {
|
|
321
|
-
self.shutdown_requested.store(true, Ordering::SeqCst);
|
|
322
|
-
self.workers.shutdown_all().await;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
async fn shutdown_worker(&self, task_queue: &str) {
|
|
326
|
-
self.workers.shutdown_one(task_queue).await;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
fn get_init_options(&self) -> &CoreInitOptions {
|
|
330
|
-
&self.init_options
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
fn fetch_buffered_logs(&self) -> Vec<CoreLog> {
|
|
334
|
-
fetch_global_buffered_logs()
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
impl CoreSDK {
|
|
339
|
-
pub(crate) fn new<SG: ServerGatewayApis + Send + Sync + 'static>(
|
|
340
|
-
server_gateway: SG,
|
|
341
|
-
init_options: CoreInitOptions,
|
|
342
|
-
) -> Self {
|
|
343
|
-
let sg = GatewayRef::new(Arc::new(server_gateway), init_options.gateway_opts.clone());
|
|
344
|
-
let workers = WorkerDispatcher::default();
|
|
345
|
-
Self {
|
|
346
|
-
workers,
|
|
347
|
-
init_options,
|
|
348
|
-
shutdown_requested: AtomicBool::new(false),
|
|
349
|
-
metrics: MetricsContext::top_level(sg.options.namespace.clone()),
|
|
350
|
-
server_gateway: Arc::new(sg),
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/// Allow construction of workers with mocked poll responses during testing
|
|
355
|
-
#[cfg(test)]
|
|
356
|
-
pub(crate) fn reg_worker_sync(&mut self, worker: MockWorker) {
|
|
357
|
-
let sticky_q = self.get_sticky_q_name_for_worker(&worker.config);
|
|
358
|
-
let tq = worker.config.task_queue.clone();
|
|
359
|
-
let worker = Worker::new_with_pollers(
|
|
360
|
-
worker.config,
|
|
361
|
-
sticky_q,
|
|
362
|
-
self.server_gateway.clone(),
|
|
363
|
-
worker.wf_poller,
|
|
364
|
-
worker.act_poller,
|
|
365
|
-
self.metrics.clone(),
|
|
366
|
-
);
|
|
367
|
-
self.workers.set_worker_for_task_queue(tq, worker).unwrap();
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
#[cfg(test)]
|
|
371
|
-
pub(crate) fn outstanding_wfts(&self, tq: &str) -> usize {
|
|
372
|
-
self.worker(tq).unwrap().outstanding_workflow_tasks()
|
|
373
|
-
}
|
|
374
|
-
#[cfg(test)]
|
|
375
|
-
pub(crate) fn available_wft_permits(&self, tq: &str) -> usize {
|
|
376
|
-
self.worker(tq).unwrap().available_wft_permits()
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
fn get_sticky_q_name_for_worker(&self, config: &WorkerConfig) -> Option<String> {
|
|
380
|
-
if config.max_cached_workflows > 0 {
|
|
381
|
-
Some(format!(
|
|
382
|
-
"{}-{}-{}",
|
|
383
|
-
&self.init_options.gateway_opts.identity, &config.task_queue, *PROCCESS_UNIQ_ID
|
|
384
|
-
))
|
|
385
|
-
} else {
|
|
386
|
-
None
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
fn worker(&self, tq: &str) -> Result<impl Deref<Target = Worker>, WorkerLookupErr> {
|
|
391
|
-
let worker = self.workers.get(tq);
|
|
392
|
-
if worker.is_err() && self.shutdown_requested.load(Ordering::Relaxed) {
|
|
393
|
-
return Err(WorkerLookupErr::Shutdown(tq.to_owned()));
|
|
394
|
-
}
|
|
395
|
-
worker
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
#[derive(Debug)]
|
|
400
|
-
enum WorkerLookupErr {
|
|
401
|
-
Shutdown(String),
|
|
402
|
-
NoWorker(String),
|
|
403
|
-
}
|