@temporalio/core-bridge 1.14.1 → 1.15.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 +648 -606
- package/bridge-macros/src/derive_tryintojs.rs +40 -0
- package/lib/native.d.ts +23 -2
- package/package.json +12 -13
- 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/.cargo/multi-worker-manual-test +0 -0
- package/sdk-core/AGENTS.md +2 -2
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/README.md +5 -5
- package/sdk-core/crates/client/src/raw.rs +90 -0
- package/sdk-core/crates/client/src/worker/mod.rs +103 -28
- package/sdk-core/crates/common/Cargo.toml +1 -1
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/create-release.yml +0 -5
- package/sdk-core/crates/common/protos/api_upstream/README.md +8 -0
- package/sdk-core/crates/common/protos/api_upstream/buf.yaml +3 -0
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +2738 -2452
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1657 -124
- 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 +26 -0
- 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 +62 -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/history/v1/message.proto +107 -17
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +15 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +4 -0
- 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 +285 -19
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +154 -10
- 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 +5 -0
- 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 +17 -0
- package/sdk-core/crates/common/src/lib.rs +3 -3
- package/sdk-core/crates/common/src/protos/canned_histories.rs +16 -0
- package/sdk-core/crates/common/src/protos/mod.rs +12 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +6 -4
- package/sdk-core/crates/common/src/telemetry.rs +14 -15
- package/sdk-core/crates/common/src/worker.rs +66 -99
- package/sdk-core/crates/common/tests/worker_task_types_test.rs +9 -9
- package/sdk-core/crates/sdk/src/lib.rs +10 -8
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +19 -0
- package/sdk-core/crates/sdk-core/Cargo.toml +2 -1
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +4 -19
- package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +9 -6
- package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +166 -13
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +42 -33
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +6 -9
- package/sdk-core/crates/sdk-core/src/lib.rs +20 -13
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +301 -21
- package/sdk-core/crates/sdk-core/src/telemetry/log_export.rs +7 -10
- package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +4 -2
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +2 -3
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +30 -8
- package/sdk-core/crates/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +1 -0
- package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +3 -1
- package/sdk-core/crates/sdk-core/src/worker/client.rs +2 -6
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +4 -4
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +92 -53
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +5 -0
- package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +12 -14
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +36 -36
- 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/workflow_machines.rs +12 -1
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +6 -23
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +46 -3
- package/sdk-core/crates/sdk-core/tests/common/mod.rs +45 -45
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +7 -10
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +34 -42
- package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +21 -26
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +147 -72
- package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +27 -48
- package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +5 -15
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +61 -66
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +16 -14
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +15 -21
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +16 -19
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +14 -9
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +2 -6
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +4 -8
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +11 -13
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +11 -27
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +4 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +7 -13
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +4 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +16 -30
- package/sdk-core/crates/sdk-core/tests/main.rs +6 -2
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +40 -49
- package/sdk-core/crates/sdk-core/tests/runner.rs +4 -6
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +28 -13
- package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +1 -0
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +24 -13
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +103 -19
- package/sdk-core/crates/sdk-core-c-bridge/src/lib.rs +89 -5
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +1 -2
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +59 -66
- 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 +46 -11
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +103 -7
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +6 -48
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +13 -17
- package/sdk-core/docker-cgroup-tests.sh +0 -0
- package/sdk-core/etc/cargo-tokio-console.sh +0 -0
- package/sdk-core/etc/integ-with-otel.sh +0 -0
- package/sdk-core/etc/regen-depgraph.sh +0 -0
- package/src/client.rs +30 -0
- package/src/helpers/try_into_js.rs +88 -2
- package/src/metrics.rs +272 -22
- package/src/runtime.rs +91 -41
- package/src/testing.rs +9 -16
- package/src/worker.rs +76 -55
- package/ts/native.ts +38 -2
- package/LICENSE +0 -21
- package/sdk-core/crates/macros/LICENSE.txt +0 -21
|
@@ -41,7 +41,6 @@ use temporalio_common::{
|
|
|
41
41
|
workflow_completion,
|
|
42
42
|
},
|
|
43
43
|
temporal::api::{
|
|
44
|
-
command::v1::command::Attributes as CmdAttribs,
|
|
45
44
|
enums::v1::{VersioningBehavior, WorkflowTaskFailedCause},
|
|
46
45
|
failure::v1::Failure,
|
|
47
46
|
},
|
|
@@ -191,6 +190,7 @@ impl ManagedRun {
|
|
|
191
190
|
attempt = %work.attempt,
|
|
192
191
|
"Applying new workflow task from server"
|
|
193
192
|
);
|
|
193
|
+
let is_incremental = work.is_incremental();
|
|
194
194
|
let wft_info = WorkflowTaskInfo {
|
|
195
195
|
attempt: work.attempt,
|
|
196
196
|
task_token: work.task_token,
|
|
@@ -239,7 +239,9 @@ impl ManagedRun {
|
|
|
239
239
|
|
|
240
240
|
// The update field is only populated in the event we hit the cache
|
|
241
241
|
let activation = if work.update.is_real() {
|
|
242
|
-
|
|
242
|
+
if is_incremental {
|
|
243
|
+
self.metrics.sticky_cache_hit();
|
|
244
|
+
}
|
|
243
245
|
self.wfm.new_work_from_server(work.update, work.messages)?
|
|
244
246
|
} else {
|
|
245
247
|
let r = self.wfm.get_next_activation()?;
|
|
@@ -440,6 +442,7 @@ impl ManagedRun {
|
|
|
440
442
|
action: ActivationAction::RespondLegacyQuery {
|
|
441
443
|
result: Box::new(qr),
|
|
442
444
|
},
|
|
445
|
+
metrics: self.metrics.clone(),
|
|
443
446
|
}),
|
|
444
447
|
resp_chan,
|
|
445
448
|
);
|
|
@@ -1127,27 +1130,6 @@ impl ManagedRun {
|
|
|
1127
1130
|
)
|
|
1128
1131
|
};
|
|
1129
1132
|
|
|
1130
|
-
// Record metrics for any outgoing terminal commands
|
|
1131
|
-
for cmd in commands.iter() {
|
|
1132
|
-
match cmd.attributes.as_ref() {
|
|
1133
|
-
Some(CmdAttribs::CompleteWorkflowExecutionCommandAttributes(_)) => {
|
|
1134
|
-
self.metrics.wf_completed();
|
|
1135
|
-
}
|
|
1136
|
-
Some(CmdAttribs::FailWorkflowExecutionCommandAttributes(attrs)) => {
|
|
1137
|
-
if metrics::should_record_failure_metric(&attrs.failure) {
|
|
1138
|
-
self.metrics.wf_failed();
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
Some(CmdAttribs::ContinueAsNewWorkflowExecutionCommandAttributes(_)) => {
|
|
1142
|
-
self.metrics.wf_continued_as_new();
|
|
1143
|
-
}
|
|
1144
|
-
Some(CmdAttribs::CancelWorkflowExecutionCommandAttributes(_)) => {
|
|
1145
|
-
self.metrics.wf_canceled();
|
|
1146
|
-
}
|
|
1147
|
-
_ => (),
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
1133
|
let attempt = self.wft.as_ref().map(|t| t.info.attempt).unwrap_or(1);
|
|
1152
1134
|
ActivationCompleteOutcome::ReportWFTSuccess(ServerCommandsWithWorkflowInfo {
|
|
1153
1135
|
task_token: data.task_token,
|
|
@@ -1160,6 +1142,7 @@ impl ManagedRun {
|
|
|
1160
1142
|
versioning_behavior: data.versioning_behavior,
|
|
1161
1143
|
attempt,
|
|
1162
1144
|
},
|
|
1145
|
+
metrics: self.metrics.clone(),
|
|
1163
1146
|
})
|
|
1164
1147
|
} else {
|
|
1165
1148
|
ActivationCompleteOutcome::DoNothing
|
|
@@ -98,8 +98,7 @@ use tokio::{
|
|
|
98
98
|
task::{LocalSet, spawn_blocking},
|
|
99
99
|
};
|
|
100
100
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
|
101
|
-
use tokio_util::either::Either;
|
|
102
|
-
use tokio_util::sync::CancellationToken;
|
|
101
|
+
use tokio_util::{either::Either, sync::CancellationToken};
|
|
103
102
|
use tracing::{Span, Subscriber};
|
|
104
103
|
|
|
105
104
|
/// Id used by server for "legacy" queries. IE: Queries that come in the `query` rather than
|
|
@@ -355,6 +354,7 @@ impl Workflows {
|
|
|
355
354
|
mut versioning_behavior,
|
|
356
355
|
attempt,
|
|
357
356
|
},
|
|
357
|
+
metrics: run_metrics,
|
|
358
358
|
} => {
|
|
359
359
|
let reserved_act_permits =
|
|
360
360
|
self.reserve_activity_slots_for_outgoing_commands(commands.as_mut_slice());
|
|
@@ -372,6 +372,7 @@ impl Workflows {
|
|
|
372
372
|
} else {
|
|
373
373
|
0
|
|
374
374
|
};
|
|
375
|
+
let mut maybe_record_terminal_metric = detect_terminal_command(&commands);
|
|
375
376
|
let mut completion = WorkflowTaskCompletion {
|
|
376
377
|
task_token: task_token.clone(),
|
|
377
378
|
commands,
|
|
@@ -398,6 +399,9 @@ impl Workflows {
|
|
|
398
399
|
self.handle_wft_reporting_errs(run_id, || async {
|
|
399
400
|
match self.client.complete_workflow_task(completion).await {
|
|
400
401
|
Ok(response) => {
|
|
402
|
+
if let Some(record) = maybe_record_terminal_metric.take() {
|
|
403
|
+
record(&run_metrics);
|
|
404
|
+
}
|
|
401
405
|
if response.reset_history_event_id > 0 {
|
|
402
406
|
reset_last_started_to = Some(response.reset_history_event_id);
|
|
403
407
|
}
|
|
@@ -460,6 +464,7 @@ impl Workflows {
|
|
|
460
464
|
ServerCommandsWithWorkflowInfo {
|
|
461
465
|
task_token,
|
|
462
466
|
action: ActivationAction::RespondLegacyQuery { result },
|
|
467
|
+
..
|
|
463
468
|
} => {
|
|
464
469
|
self.respond_legacy_query(task_token, LegacyQueryResult::Succeeded(*result))
|
|
465
470
|
.await;
|
|
@@ -1008,10 +1013,18 @@ enum FailedActivationWFTReport {
|
|
|
1008
1013
|
ReportLegacyQueryFailure(TaskToken, Failure),
|
|
1009
1014
|
}
|
|
1010
1015
|
|
|
1011
|
-
#[derive(Debug)]
|
|
1012
1016
|
struct ServerCommandsWithWorkflowInfo {
|
|
1013
1017
|
task_token: TaskToken,
|
|
1014
1018
|
action: ActivationAction,
|
|
1019
|
+
metrics: MetricsContext,
|
|
1020
|
+
}
|
|
1021
|
+
impl Debug for ServerCommandsWithWorkflowInfo {
|
|
1022
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
1023
|
+
f.debug_struct("ServerCommandsWithWorkflowInfo")
|
|
1024
|
+
.field("task_token", &self.task_token)
|
|
1025
|
+
.field("action", &self.action)
|
|
1026
|
+
.finish()
|
|
1027
|
+
}
|
|
1015
1028
|
}
|
|
1016
1029
|
|
|
1017
1030
|
#[derive(Debug)]
|
|
@@ -1031,6 +1044,7 @@ pub(crate) enum ActivationAction {
|
|
|
1031
1044
|
}
|
|
1032
1045
|
|
|
1033
1046
|
#[derive(Debug)]
|
|
1047
|
+
#[allow(clippy::large_enum_variant)]
|
|
1034
1048
|
enum EvictionRequestResult {
|
|
1035
1049
|
EvictionRequested(Option<u32>, RunUpdateAct),
|
|
1036
1050
|
NotFound,
|
|
@@ -1046,6 +1060,35 @@ impl EvictionRequestResult {
|
|
|
1046
1060
|
}
|
|
1047
1061
|
}
|
|
1048
1062
|
|
|
1063
|
+
#[allow(clippy::type_complexity)]
|
|
1064
|
+
fn detect_terminal_command(
|
|
1065
|
+
commands: &[ProtoCommand],
|
|
1066
|
+
) -> Option<Box<dyn FnOnce(&MetricsContext) + Send>> {
|
|
1067
|
+
for cmd in commands {
|
|
1068
|
+
match cmd.attributes.as_ref() {
|
|
1069
|
+
Some(Attributes::CompleteWorkflowExecutionCommandAttributes(_)) => {
|
|
1070
|
+
return Some(Box::new(|m: &MetricsContext| m.wf_completed()));
|
|
1071
|
+
}
|
|
1072
|
+
Some(Attributes::FailWorkflowExecutionCommandAttributes(attrs)) => {
|
|
1073
|
+
let should_record = metrics::should_record_failure_metric(&attrs.failure);
|
|
1074
|
+
return Some(Box::new(move |m: &MetricsContext| {
|
|
1075
|
+
if should_record {
|
|
1076
|
+
m.wf_failed();
|
|
1077
|
+
}
|
|
1078
|
+
}));
|
|
1079
|
+
}
|
|
1080
|
+
Some(Attributes::ContinueAsNewWorkflowExecutionCommandAttributes(_)) => {
|
|
1081
|
+
return Some(Box::new(|m: &MetricsContext| m.wf_continued_as_new()));
|
|
1082
|
+
}
|
|
1083
|
+
Some(Attributes::CancelWorkflowExecutionCommandAttributes(_)) => {
|
|
1084
|
+
return Some(Box::new(|m: &MetricsContext| m.wf_canceled()));
|
|
1085
|
+
}
|
|
1086
|
+
_ => {}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
None
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1049
1092
|
#[derive(Debug)]
|
|
1050
1093
|
#[allow(dead_code)] // Not always used in non-test
|
|
1051
1094
|
pub(crate) struct WorkflowStateInfo {
|
|
@@ -46,8 +46,7 @@ use temporalio_common::{
|
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
telemetry::{
|
|
49
|
-
Logger,
|
|
50
|
-
PrometheusExporterOptionsBuilder, TelemetryOptions, TelemetryOptionsBuilder,
|
|
49
|
+
Logger, OtelCollectorOptions, PrometheusExporterOptions, TelemetryOptions,
|
|
51
50
|
metrics::CoreMeter,
|
|
52
51
|
},
|
|
53
52
|
worker::{WorkerTaskTypes, WorkerVersioningStrategy},
|
|
@@ -62,8 +61,7 @@ use temporalio_sdk::{
|
|
|
62
61
|
#[cfg(any(feature = "test-utilities", test))]
|
|
63
62
|
pub(crate) use temporalio_sdk_core::test_help::NAMESPACE;
|
|
64
63
|
use temporalio_sdk_core::{
|
|
65
|
-
ClientOptions, CoreRuntime, RuntimeOptions,
|
|
66
|
-
WorkerConfigBuilder, init_replay_worker, init_worker,
|
|
64
|
+
ClientOptions, CoreRuntime, RuntimeOptions, WorkerConfig, init_replay_worker, init_worker,
|
|
67
65
|
replay::{HistoryForReplay, ReplayWorkerInput},
|
|
68
66
|
telemetry::{build_otlp_metric_exporter, start_prometheus_metric_exporter},
|
|
69
67
|
test_help::{MockPollCfg, build_mock_pollers, mock_worker},
|
|
@@ -101,9 +99,9 @@ pub(crate) async fn init_core_and_create_wf(test_name: &str) -> CoreWfStarter {
|
|
|
101
99
|
starter
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
pub(crate) fn integ_worker_config(tq: &str) ->
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
pub(crate) fn integ_worker_config(tq: &str) -> WorkerConfig {
|
|
103
|
+
WorkerConfig::builder()
|
|
104
|
+
.namespace(env::var(INTEG_NAMESPACE_ENV_VAR).unwrap_or(NAMESPACE.to_string()))
|
|
107
105
|
.task_queue(tq)
|
|
108
106
|
.max_outstanding_activities(100_usize)
|
|
109
107
|
.max_outstanding_local_activities(100_usize)
|
|
@@ -112,8 +110,9 @@ pub(crate) fn integ_worker_config(tq: &str) -> WorkerConfigBuilder {
|
|
|
112
110
|
build_id: "test_build_id".to_owned(),
|
|
113
111
|
})
|
|
114
112
|
.task_types(WorkerTaskTypes::all())
|
|
115
|
-
.skip_client_worker_set_check(true)
|
|
116
|
-
|
|
113
|
+
.skip_client_worker_set_check(true)
|
|
114
|
+
.build()
|
|
115
|
+
.expect("Configuration options construct properly")
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
/// Create a worker replay instance preloaded with provided histories. Returns the worker impl.
|
|
@@ -129,9 +128,7 @@ where
|
|
|
129
128
|
I: Stream<Item = HistoryForReplay> + Send + 'static,
|
|
130
129
|
{
|
|
131
130
|
init_integ_telem();
|
|
132
|
-
let worker_cfg = integ_worker_config(test_name)
|
|
133
|
-
.build()
|
|
134
|
-
.expect("Configuration options construct properly");
|
|
131
|
+
let worker_cfg = integ_worker_config(test_name);
|
|
135
132
|
let worker = init_replay_worker(ReplayWorkerInput::new(worker_cfg, histories))
|
|
136
133
|
.expect("Replay worker must init properly");
|
|
137
134
|
Arc::new(worker)
|
|
@@ -177,7 +174,7 @@ pub(crate) fn init_integ_telem() -> Option<&'static CoreRuntime> {
|
|
|
177
174
|
}
|
|
178
175
|
Some(INTEG_TESTS_RT.get_or_init(|| {
|
|
179
176
|
let telemetry_options = get_integ_telem_options();
|
|
180
|
-
let runtime_options =
|
|
177
|
+
let runtime_options = RuntimeOptions::builder()
|
|
181
178
|
.telemetry_options(telemetry_options)
|
|
182
179
|
.build()
|
|
183
180
|
.expect("Runtime options build cleanly");
|
|
@@ -224,7 +221,7 @@ pub(crate) async fn get_cloud_client() -> RetryClient<Client> {
|
|
|
224
221
|
pub(crate) struct CoreWfStarter {
|
|
225
222
|
/// Used for both the task queue and workflow id
|
|
226
223
|
task_queue_name: String,
|
|
227
|
-
pub worker_config:
|
|
224
|
+
pub worker_config: WorkerConfig,
|
|
228
225
|
/// Options to use when starting workflow(s)
|
|
229
226
|
pub workflow_options: WorkflowOptions,
|
|
230
227
|
initted_worker: OnceCell<InitializedWorker>,
|
|
@@ -299,9 +296,7 @@ impl CoreWfStarter {
|
|
|
299
296
|
let task_q_salt = rand_6_chars();
|
|
300
297
|
let task_queue = format!("{test_name}_{task_q_salt}");
|
|
301
298
|
let mut worker_config = integ_worker_config(&task_queue);
|
|
302
|
-
worker_config
|
|
303
|
-
.namespace(env::var(INTEG_NAMESPACE_ENV_VAR).unwrap_or(NAMESPACE.to_string()))
|
|
304
|
-
.max_cached_workflows(1000_usize);
|
|
299
|
+
worker_config.max_cached_workflows = 1000_usize;
|
|
305
300
|
Self {
|
|
306
301
|
task_queue_name: task_queue,
|
|
307
302
|
worker_config,
|
|
@@ -452,10 +447,7 @@ impl CoreWfStarter {
|
|
|
452
447
|
} else {
|
|
453
448
|
init_integ_telem().unwrap()
|
|
454
449
|
};
|
|
455
|
-
let cfg = self
|
|
456
|
-
.worker_config
|
|
457
|
-
.build()
|
|
458
|
-
.expect("Worker config must be valid");
|
|
450
|
+
let cfg = self.worker_config.clone();
|
|
459
451
|
let client = if let Some(client) = self.client_override.take() {
|
|
460
452
|
client
|
|
461
453
|
} else {
|
|
@@ -794,41 +786,47 @@ pub(crate) fn get_integ_tls_config() -> Option<TlsOptions> {
|
|
|
794
786
|
}
|
|
795
787
|
|
|
796
788
|
pub(crate) fn get_integ_telem_options() -> TelemetryOptions {
|
|
797
|
-
let mut ob = TelemetryOptionsBuilder::default();
|
|
798
789
|
let filter_string =
|
|
799
790
|
env::var("RUST_LOG").unwrap_or_else(|_| "INFO,temporalio_sdk_core=INFO".to_string());
|
|
791
|
+
|
|
800
792
|
if let Some(url) = env::var(OTEL_URL_ENV_VAR)
|
|
801
793
|
.ok()
|
|
802
794
|
.map(|x| x.parse::<Url>().unwrap())
|
|
803
795
|
{
|
|
804
|
-
let opts =
|
|
805
|
-
|
|
796
|
+
let opts = OtelCollectorOptions::builder().url(url).build();
|
|
797
|
+
TelemetryOptions::builder()
|
|
798
|
+
.metrics(Arc::new(build_otlp_metric_exporter(opts).unwrap()) as Arc<dyn CoreMeter>)
|
|
799
|
+
.logging(Logger::Console {
|
|
800
|
+
filter: filter_string,
|
|
801
|
+
})
|
|
806
802
|
.build()
|
|
807
|
-
|
|
808
|
-
ob.metrics(Arc::new(build_otlp_metric_exporter(opts).unwrap()) as Arc<dyn CoreMeter>);
|
|
809
|
-
}
|
|
810
|
-
if let Some(addr) = env::var(PROM_ENABLE_ENV_VAR)
|
|
803
|
+
} else if let Some(addr) = env::var(PROM_ENABLE_ENV_VAR)
|
|
811
804
|
.ok()
|
|
812
805
|
.map(|x| SocketAddr::new([127, 0, 0, 1].into(), x.parse().unwrap()))
|
|
813
806
|
{
|
|
814
807
|
let prom_info = start_prometheus_metric_exporter(
|
|
815
|
-
|
|
808
|
+
PrometheusExporterOptions::builder()
|
|
816
809
|
.socket_addr(addr)
|
|
817
|
-
.build()
|
|
818
|
-
.unwrap(),
|
|
810
|
+
.build(),
|
|
819
811
|
)
|
|
820
812
|
.unwrap();
|
|
821
|
-
|
|
813
|
+
TelemetryOptions::builder()
|
|
814
|
+
.metrics(prom_info.meter as Arc<dyn CoreMeter>)
|
|
815
|
+
.logging(Logger::Console {
|
|
816
|
+
filter: filter_string,
|
|
817
|
+
})
|
|
818
|
+
.build()
|
|
819
|
+
} else {
|
|
820
|
+
TelemetryOptions::builder()
|
|
821
|
+
.logging(Logger::Console {
|
|
822
|
+
filter: filter_string,
|
|
823
|
+
})
|
|
824
|
+
.build()
|
|
822
825
|
}
|
|
823
|
-
ob.logging(Logger::Console {
|
|
824
|
-
filter: filter_string,
|
|
825
|
-
})
|
|
826
|
-
.build()
|
|
827
|
-
.unwrap()
|
|
828
826
|
}
|
|
829
827
|
|
|
830
828
|
pub(crate) fn get_integ_runtime_options(telemopts: TelemetryOptions) -> RuntimeOptions {
|
|
831
|
-
|
|
829
|
+
RuntimeOptions::builder()
|
|
832
830
|
.telemetry_options(telemopts)
|
|
833
831
|
.build()
|
|
834
832
|
.unwrap()
|
|
@@ -886,10 +884,9 @@ pub(crate) fn prom_metrics(
|
|
|
886
884
|
options_override: Option<PrometheusExporterOptions>,
|
|
887
885
|
) -> (TelemetryOptions, SocketAddr, AbortOnDrop) {
|
|
888
886
|
let prom_exp_opts = options_override.unwrap_or_else(|| {
|
|
889
|
-
|
|
887
|
+
PrometheusExporterOptions::builder()
|
|
890
888
|
.socket_addr(ANY_PORT.parse().unwrap())
|
|
891
889
|
.build()
|
|
892
|
-
.unwrap()
|
|
893
890
|
});
|
|
894
891
|
let mut telemopts = get_integ_telem_options();
|
|
895
892
|
let prom_info = start_prometheus_metric_exporter(prom_exp_opts).unwrap();
|
|
@@ -998,13 +995,14 @@ impl Drop for ActivationAssertionsInterceptor {
|
|
|
998
995
|
|
|
999
996
|
#[cfg(feature = "ephemeral-server")]
|
|
1000
997
|
use temporalio_sdk_core::ephemeral_server::{
|
|
1001
|
-
EphemeralExe, EphemeralExeVersion,
|
|
998
|
+
EphemeralExe, EphemeralExeVersion, TemporalDevServerConfig, default_cached_download,
|
|
1002
999
|
};
|
|
1003
1000
|
|
|
1004
1001
|
#[cfg(feature = "ephemeral-server")]
|
|
1005
1002
|
pub(crate) fn integ_dev_server_config(
|
|
1006
1003
|
mut extra_args: Vec<String>,
|
|
1007
|
-
|
|
1004
|
+
ui: bool,
|
|
1005
|
+
) -> TemporalDevServerConfig {
|
|
1008
1006
|
let cli_version = if let Ok(ver_override) = env::var(CLI_VERSION_OVERRIDE_ENV_VAR) {
|
|
1009
1007
|
EphemeralExe::CachedDownload {
|
|
1010
1008
|
version: EphemeralExeVersion::Fixed(ver_override.to_owned()),
|
|
@@ -1041,7 +1039,9 @@ pub(crate) fn integ_dev_server_config(
|
|
|
1041
1039
|
.map(Into::into),
|
|
1042
1040
|
);
|
|
1043
1041
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1042
|
+
TemporalDevServerConfig::builder()
|
|
1043
|
+
.exe(cli_version)
|
|
1044
|
+
.extra_args(extra_args)
|
|
1045
|
+
.ui(ui)
|
|
1046
|
+
.build()
|
|
1047
1047
|
}
|
|
@@ -7,7 +7,7 @@ use common::CoreWfStarter;
|
|
|
7
7
|
use parking_lot::Mutex;
|
|
8
8
|
use std::{sync::Arc, time::Duration};
|
|
9
9
|
use temporalio_common::telemetry::{
|
|
10
|
-
Logger,
|
|
10
|
+
Logger, OtelCollectorOptions, TelemetryOptions, metrics::CoreMeter,
|
|
11
11
|
};
|
|
12
12
|
use temporalio_sdk_core::{
|
|
13
13
|
CoreRuntime,
|
|
@@ -58,28 +58,25 @@ async fn otel_errors_logged_as_errors() {
|
|
|
58
58
|
.with_env_filter("debug")
|
|
59
59
|
.finish(),
|
|
60
60
|
);
|
|
61
|
-
let opts =
|
|
61
|
+
let opts = OtelCollectorOptions::builder()
|
|
62
62
|
.url("https://localhost:12345/v1/metrics".parse().unwrap()) // Nothing bound on that port
|
|
63
|
-
.build()
|
|
64
|
-
.unwrap();
|
|
63
|
+
.build();
|
|
65
64
|
let exporter = build_otlp_metric_exporter(opts).unwrap();
|
|
66
65
|
|
|
67
66
|
// Global initialization is needed to capture (some) otel logging.
|
|
68
67
|
telemetry_init_global(
|
|
69
|
-
|
|
68
|
+
TelemetryOptions::builder()
|
|
70
69
|
.subscriber_override(subscriber)
|
|
71
|
-
.build()
|
|
72
|
-
.unwrap(),
|
|
70
|
+
.build(),
|
|
73
71
|
)
|
|
74
72
|
.unwrap();
|
|
75
|
-
let telemopts =
|
|
73
|
+
let telemopts = TelemetryOptions::builder()
|
|
76
74
|
.metrics(Arc::new(exporter) as Arc<dyn CoreMeter>)
|
|
77
75
|
// Importantly, _not_ using subscriber override, is using console.
|
|
78
76
|
.logging(Logger::Console {
|
|
79
77
|
filter: construct_filter_string(Level::INFO, Level::WARN),
|
|
80
78
|
})
|
|
81
|
-
.build()
|
|
82
|
-
.unwrap();
|
|
79
|
+
.build();
|
|
83
80
|
|
|
84
81
|
let rt = CoreRuntime::new_assume_tokio(get_integ_runtime_options(telemopts)).unwrap();
|
|
85
82
|
let mut starter = CoreWfStarter::new_with_runtime("otel_errors_logged_as_errors", rt);
|
|
@@ -77,11 +77,9 @@ async fn fuzzy_workflow() {
|
|
|
77
77
|
let num_workflows = 200;
|
|
78
78
|
let wf_name = "fuzzy_wf";
|
|
79
79
|
let mut starter = CoreWfStarter::new("fuzzy_workflow");
|
|
80
|
-
starter
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
.max_cached_workflows(25_usize)
|
|
84
|
-
.max_outstanding_activities(25_usize);
|
|
80
|
+
starter.worker_config.max_outstanding_workflow_tasks = Some(25);
|
|
81
|
+
starter.worker_config.max_cached_workflows = 25;
|
|
82
|
+
starter.worker_config.max_outstanding_activities = Some(25);
|
|
85
83
|
let mut worker = starter.worker().await;
|
|
86
84
|
worker.register_wf(wf_name.to_owned(), fuzzy_wf_def);
|
|
87
85
|
worker.register_activity("echo_activity", echo);
|
|
@@ -40,12 +40,10 @@ async fn activity_load() {
|
|
|
40
40
|
const CONCURRENCY: usize = 512;
|
|
41
41
|
|
|
42
42
|
let mut starter = CoreWfStarter::new("activity_load");
|
|
43
|
-
starter
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.activity_task_poller_behavior(PollerBehavior::SimpleMaximum(10_usize))
|
|
48
|
-
.max_outstanding_activities(CONCURRENCY);
|
|
43
|
+
starter.worker_config.max_outstanding_workflow_tasks = Some(CONCURRENCY);
|
|
44
|
+
starter.worker_config.max_cached_workflows = CONCURRENCY;
|
|
45
|
+
starter.worker_config.activity_task_poller_behavior = PollerBehavior::SimpleMaximum(10);
|
|
46
|
+
starter.worker_config.max_outstanding_activities = Some(CONCURRENCY);
|
|
49
47
|
let mut worker = starter.worker().await;
|
|
50
48
|
|
|
51
49
|
let activity_id = "act-1";
|
|
@@ -110,11 +108,12 @@ async fn chunky_activities_resource_based() {
|
|
|
110
108
|
const WORKFLOWS: usize = 100;
|
|
111
109
|
|
|
112
110
|
let mut starter = CoreWfStarter::new("chunky_activities_resource_based");
|
|
113
|
-
starter
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
starter.worker_config.max_outstanding_workflow_tasks = None;
|
|
112
|
+
starter.worker_config.max_outstanding_local_activities = None;
|
|
113
|
+
starter.worker_config.max_outstanding_activities = None;
|
|
114
|
+
starter.worker_config.max_outstanding_nexus_tasks = None;
|
|
115
|
+
starter.worker_config.workflow_task_poller_behavior = PollerBehavior::SimpleMaximum(10_usize);
|
|
116
|
+
starter.worker_config.activity_task_poller_behavior = PollerBehavior::SimpleMaximum(10_usize);
|
|
118
117
|
let mut tuner = ResourceBasedTuner::new(0.7, 0.7);
|
|
119
118
|
tuner
|
|
120
119
|
.with_workflow_slots_options(ResourceSlotOptions::new(
|
|
@@ -123,7 +122,7 @@ async fn chunky_activities_resource_based() {
|
|
|
123
122
|
Duration::from_millis(0),
|
|
124
123
|
))
|
|
125
124
|
.with_activity_slots_options(ResourceSlotOptions::new(5, 1000, Duration::from_millis(50)));
|
|
126
|
-
starter.worker_config.tuner(Arc::new(tuner));
|
|
125
|
+
starter.worker_config.tuner = Some(Arc::new(tuner));
|
|
127
126
|
let mut worker = starter.worker().await;
|
|
128
127
|
|
|
129
128
|
let activity_id = "act-1";
|
|
@@ -174,6 +173,7 @@ async fn chunky_activities_resource_based() {
|
|
|
174
173
|
wf_type.to_owned(),
|
|
175
174
|
vec![],
|
|
176
175
|
WorkflowOptions {
|
|
176
|
+
#[allow(deprecated)]
|
|
177
177
|
id_reuse_policy: WorkflowIdReusePolicy::TerminateIfRunning,
|
|
178
178
|
..Default::default()
|
|
179
179
|
},
|
|
@@ -203,12 +203,10 @@ async fn workflow_load() {
|
|
|
203
203
|
init_integ_telem();
|
|
204
204
|
let rt = CoreRuntime::new_assume_tokio(get_integ_runtime_options(telemopts)).unwrap();
|
|
205
205
|
let mut starter = CoreWfStarter::new_with_runtime("workflow_load", rt);
|
|
206
|
-
starter
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
.activity_task_poller_behavior(PollerBehavior::SimpleMaximum(10_usize))
|
|
211
|
-
.max_outstanding_activities(100_usize);
|
|
206
|
+
starter.worker_config.max_outstanding_workflow_tasks = Some(5);
|
|
207
|
+
starter.worker_config.max_cached_workflows = 200;
|
|
208
|
+
starter.worker_config.activity_task_poller_behavior = PollerBehavior::SimpleMaximum(10);
|
|
209
|
+
starter.worker_config.max_outstanding_activities = Some(100);
|
|
212
210
|
let mut worker = starter.worker().await;
|
|
213
211
|
worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
|
|
214
212
|
let sigchan = ctx.make_signal_channel(SIGNAME).map(Ok);
|
|
@@ -282,10 +280,8 @@ async fn workflow_load() {
|
|
|
282
280
|
async fn evict_while_la_running_no_interference() {
|
|
283
281
|
let wf_name = "evict_while_la_running_no_interference";
|
|
284
282
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
285
|
-
starter
|
|
286
|
-
|
|
287
|
-
.max_outstanding_local_activities(20_usize)
|
|
288
|
-
.max_cached_workflows(20_usize);
|
|
283
|
+
starter.worker_config.max_outstanding_local_activities = Some(20);
|
|
284
|
+
starter.worker_config.max_cached_workflows = 20;
|
|
289
285
|
// Though it doesn't make sense to set wft higher than cached workflows, leaving this commented
|
|
290
286
|
// introduces more instability that can be useful in the test.
|
|
291
287
|
// starter.max_wft(20);
|
|
@@ -350,11 +346,9 @@ pub async fn many_parallel_timers_longhist(ctx: WfContext) -> WorkflowResult<()>
|
|
|
350
346
|
async fn can_paginate_long_history() {
|
|
351
347
|
let wf_name = "can_paginate_long_history";
|
|
352
348
|
let mut starter = CoreWfStarter::new(wf_name);
|
|
353
|
-
starter
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
// Do not use sticky queues so we are forced to paginate once history gets long
|
|
357
|
-
.max_cached_workflows(0_usize);
|
|
349
|
+
starter.worker_config.task_types = WorkerTaskTypes::workflow_only();
|
|
350
|
+
// Do not use sticky queues so we are forced to paginate once history gets long
|
|
351
|
+
starter.worker_config.max_cached_workflows = 0;
|
|
358
352
|
|
|
359
353
|
let mut worker = starter.worker().await;
|
|
360
354
|
worker.register_wf(wf_name.to_owned(), many_parallel_timers_longhist);
|
|
@@ -394,21 +388,19 @@ async fn poller_autoscaling_basic_loadtest() {
|
|
|
394
388
|
let num_workflows = 100;
|
|
395
389
|
let wf_name = "poller_load";
|
|
396
390
|
let mut starter = CoreWfStarter::new("poller_load");
|
|
397
|
-
starter
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
initial: 5,
|
|
411
|
-
});
|
|
391
|
+
starter.worker_config.max_cached_workflows = 5000;
|
|
392
|
+
starter.worker_config.max_outstanding_workflow_tasks = Some(1000);
|
|
393
|
+
starter.worker_config.max_outstanding_activities = Some(1000);
|
|
394
|
+
starter.worker_config.workflow_task_poller_behavior = PollerBehavior::Autoscaling {
|
|
395
|
+
minimum: 1,
|
|
396
|
+
maximum: 200,
|
|
397
|
+
initial: 5,
|
|
398
|
+
};
|
|
399
|
+
starter.worker_config.activity_task_poller_behavior = PollerBehavior::Autoscaling {
|
|
400
|
+
minimum: 1,
|
|
401
|
+
maximum: 200,
|
|
402
|
+
initial: 5,
|
|
403
|
+
};
|
|
412
404
|
let mut worker = starter.worker().await;
|
|
413
405
|
let shutdown_handle = worker.inner_mut().shutdown_handle();
|
|
414
406
|
worker.register_wf(wf_name.to_owned(), |ctx: WfContext| async move {
|