From a4de7caf52298903cd76e359be04bd244ccf389d Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Tue, 21 Oct 2025 16:43:25 -0400 Subject: [PATCH 01/18] update core --- packages/core-bridge/Cargo.lock | 153 +++++++++++++++++----------- packages/core-bridge/Cargo.toml | 22 ++-- packages/core-bridge/sdk-core | 2 +- packages/core-bridge/src/runtime.rs | 12 ++- 4 files changed, 117 insertions(+), 72 deletions(-) diff --git a/packages/core-bridge/Cargo.lock b/packages/core-bridge/Cargo.lock index a3f0f9339..c3e0f6f6f 100644 --- a/packages/core-bridge/Cargo.lock +++ b/packages/core-bridge/Cargo.lock @@ -1375,23 +1375,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "opentelemetry" -version = "0.29.1" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e87237e2775f74896f9ad219d26a2081751187eb7c9f5c58dde20a23b95d16c" -dependencies = [ - "futures-core", - "futures-sink", - "js-sys", - "pin-project-lite", - "thiserror 2.0.14", - "tracing", -] - -[[package]] -name = "opentelemetry" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6" +checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" dependencies = [ "futures-core", "futures-sink", @@ -1403,25 +1389,25 @@ dependencies = [ [[package]] name = "opentelemetry-http" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d" +checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" dependencies = [ "async-trait", "bytes", "http", - "opentelemetry 0.30.0", + "opentelemetry", "reqwest", ] [[package]] name = "opentelemetry-otlp" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" +checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" dependencies = [ "http", - "opentelemetry 0.30.0", + "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry_sdk", @@ -1435,29 +1421,29 @@ dependencies = [ [[package]] name = "opentelemetry-proto" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc" +checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" dependencies = [ - "opentelemetry 0.30.0", + "opentelemetry", "opentelemetry_sdk", "prost", "tonic", + "tonic-prost", ] [[package]] name = "opentelemetry_sdk" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b" +checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" dependencies = [ "futures-channel", "futures-executor", "futures-util", - "opentelemetry 0.30.0", + "opentelemetry", "percent-encoding", "rand 0.9.2", - "serde_json", "thiserror 2.0.14", "tokio", "tokio-stream", @@ -1654,9 +1640,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" dependencies = [ "bytes", "prost-derive", @@ -1664,9 +1650,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" dependencies = [ "heck", "itertools", @@ -1677,6 +1663,8 @@ dependencies = [ "prettyplease", "prost", "prost-types", + "pulldown-cmark", + "pulldown-cmark-to-cmark", "regex", "syn", "tempfile", @@ -1684,9 +1672,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" dependencies = [ "anyhow", "itertools", @@ -1697,18 +1685,18 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" dependencies = [ "prost", ] [[package]] name = "prost-wkt" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497e1e938f0c09ef9cabe1d49437b4016e03e8f82fbbe5d1c62a9b61b9decae1" +checksum = "655944d0ce015e71b3ec21279437e6a09e58433e50c7b0677901f3d5235e74f5" dependencies = [ "chrono", "inventory", @@ -1721,9 +1709,9 @@ dependencies = [ [[package]] name = "prost-wkt-build" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b8bf115b70a7aa5af1fd5d6e9418492e9ccb6e4785e858c938e28d132a884b" +checksum = "f869f1443fee474b785e935d92e1007f57443e485f51668ed41943fc01a321a2" dependencies = [ "heck", "prost", @@ -1734,9 +1722,9 @@ dependencies = [ [[package]] name = "prost-wkt-types" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cdde6df0a98311c839392ca2f2f0bcecd545f86a62b4e3c6a49c336e970fe5" +checksum = "eeeffd6b9becd4600dd461399f3f71aeda2ff0848802a9ed526cf12e8f42902a" dependencies = [ "chrono", "prost", @@ -1770,6 +1758,26 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "pulldown-cmark" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "pulldown-cmark-to-cmark" +version = "21.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b6a0769a491a08b31ea5c62494a8f144ee0987d86d670a8af4df1e1b7cde75" +dependencies = [ + "pulldown-cmark", +] + [[package]] name = "quanta" version = "0.12.6" @@ -2459,7 +2467,7 @@ dependencies = [ "itertools", "lru", "mockall", - "opentelemetry 0.30.0", + "opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", "parking_lot", @@ -2500,7 +2508,7 @@ dependencies = [ "async-trait", "derive_builder", "derive_more", - "opentelemetry 0.30.0", + "opentelemetry", "prost", "serde_json", "temporal-sdk-core-protos", @@ -2509,6 +2517,7 @@ dependencies = [ "tracing", "tracing-core", "url", + "uuid", ] [[package]] @@ -2519,16 +2528,15 @@ dependencies = [ "base64", "derive_more", "prost", - "prost-build", "prost-wkt", - "prost-wkt-build", "prost-wkt-types", "rand 0.9.2", "serde", "serde_json", "thiserror 2.0.14", "tonic", - "tonic-build", + "tonic-prost", + "tonic-prost-build", "uuid", ] @@ -2541,7 +2549,7 @@ dependencies = [ "bridge-macros", "futures", "neon", - "opentelemetry 0.29.1", + "opentelemetry", "os_pipe", "parking_lot", "prost", @@ -2705,9 +2713,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.13.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9" +checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" dependencies = [ "async-trait", "axum", @@ -2722,9 +2730,9 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "prost", "rustls-native-certs", - "socket2 0.5.10", + "socket2 0.6.0", + "sync_wrapper", "tokio", "tokio-rustls", "tokio-stream", @@ -2736,9 +2744,32 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.13.1" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40aaccc9f9eccf2cd82ebc111adc13030d23e887244bc9cfa5d1d636049de3" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tonic-prost" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac6f67be712d12f0b41328db3137e0d0757645d8904b4cb7d51cd9c2279e847" +checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tonic-prost-build" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a16cba4043dc3ff43fcb3f96b4c5c154c64cbd18ca8dce2ab2c6a451d058a2" dependencies = [ "prettyplease", "proc-macro2", @@ -2746,6 +2777,8 @@ dependencies = [ "prost-types", "quote", "syn", + "tempfile", + "tonic-build", ] [[package]] @@ -2882,6 +2915,12 @@ dependencies = [ "syn", ] +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -2925,9 +2964,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", diff --git a/packages/core-bridge/Cargo.toml b/packages/core-bridge/Cargo.toml index 1831c7b59..ecc4e78e0 100644 --- a/packages/core-bridge/Cargo.toml +++ b/packages/core-bridge/Cargo.toml @@ -25,28 +25,28 @@ async-trait = "0.1.83" bridge-macros = { path = "bridge-macros" } futures = { version = "0.3", features = ["executor"] } neon = { version = "1.0.0", default-features = false, features = [ - "napi-6", - "futures", + "napi-6", + "futures", ] } -opentelemetry = "0.29" +opentelemetry = "0.31" os_pipe = "1.2.1" parking_lot = "0.12" -prost = "0.13" -prost-types = "0.13" +prost = "0.14" +prost-types = "0.14" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" temporal-sdk-core = { version = "*", path = "./sdk-core/core", features = [ - "ephemeral-server", + "ephemeral-server", ] } temporal-client = { version = "*", path = "./sdk-core/client" } thiserror = "2" tokio = "1.13" tokio-stream = "0.1" -tonic = "0.13" +tonic = "0.14" tracing = "0.1" tracing-subscriber = { version = "0.3", default-features = false, features = [ - "parking_lot", - "env-filter", - "registry", - "ansi", + "parking_lot", + "env-filter", + "registry", + "ansi", ] } diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index de674173c..9e9a46191 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit de674173c664d42f85d0dee1ff3b2ac47e36d545 +Subproject commit 9e9a46191656fc9ccd95589dac3552410561d620 diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index 42ad067ef..d54a16444 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -6,7 +6,7 @@ use neon::prelude::*; use tracing::{Instrument, warn}; use temporal_sdk_core::{ - CoreRuntime, TokioRuntimeBuilder, + CoreRuntime, RuntimeOptionsBuilder, TokioRuntimeBuilder, api::telemetry::{ CoreLog, OtelCollectorOptions as CoreOtelCollectorOptions, PrometheusExporterOptions as CorePrometheusExporterOptions, metrics::CoreMeter, @@ -62,8 +62,14 @@ pub fn runtime_new( let (telemetry_options, metrics_options, logging_options) = bridge_options.try_into()?; // Create core runtime which starts tokio multi-thread runtime - let mut core_runtime = CoreRuntime::new(telemetry_options, TokioRuntimeBuilder::default()) - .context("Failed to initialize Core Runtime")?; + let mut core_runtime = CoreRuntime::new( + RuntimeOptionsBuilder::default() + .telemetry_options(telemetry_options) + .build() + .expect("RuntimeOptionsBuilder to never fail as every field has a default"), + TokioRuntimeBuilder::default(), + ) + .context("Failed to initialize Core Runtime")?; enter_sync!(core_runtime); From 3fe05d561c4611f8d88bc2ab0598bcdad691df0d Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 10:39:49 -0400 Subject: [PATCH 02/18] update imports --- packages/core-bridge/Cargo.lock | 165 ++++++++---------- packages/core-bridge/Cargo.toml | 5 +- packages/core-bridge/sdk-core | 2 +- packages/core-bridge/src/client.rs | 16 +- .../core-bridge/src/helpers/try_from_js.rs | 2 +- packages/core-bridge/src/logs.rs | 2 +- packages/core-bridge/src/metrics.rs | 6 +- packages/core-bridge/src/runtime.rs | 27 ++- packages/core-bridge/src/testing.rs | 6 +- packages/core-bridge/src/worker.rs | 61 +++---- packages/proto/scripts/compile-proto.js | 2 +- 11 files changed, 131 insertions(+), 163 deletions(-) diff --git a/packages/core-bridge/Cargo.lock b/packages/core-bridge/Cargo.lock index c3e0f6f6f..b92fc0455 100644 --- a/packages/core-bridge/Cargo.lock +++ b/packages/core-bridge/Cargo.lock @@ -2048,29 +2048,6 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" -[[package]] -name = "rustfsm" -version = "0.1.0" -dependencies = [ - "rustfsm_procmacro", - "rustfsm_trait", -] - -[[package]] -name = "rustfsm_procmacro" -version = "0.1.0" -dependencies = [ - "derive_more", - "proc-macro2", - "quote", - "rustfsm_trait", - "syn", -] - -[[package]] -name = "rustfsm_trait" -version = "0.1.0" - [[package]] name = "rustix" version = "1.0.8" @@ -2412,7 +2389,34 @@ dependencies = [ ] [[package]] -name = "temporal-client" +name = "temporal-sdk-typescript-bridge" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "bridge-macros", + "futures", + "neon", + "opentelemetry", + "os_pipe", + "parking_lot", + "prost", + "prost-types", + "serde", + "serde_json", + "temporalio-client", + "temporalio-common", + "temporalio-sdk-core", + "thiserror 2.0.14", + "tokio", + "tokio-stream", + "tonic", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "temporalio-client" version = "0.1.0" dependencies = [ "anyhow", @@ -2431,8 +2435,7 @@ dependencies = [ "hyper-util", "parking_lot", "slotmap", - "temporal-sdk-core-api", - "temporal-sdk-core-protos", + "temporalio-common", "thiserror 2.0.14", "tokio", "tonic", @@ -2443,7 +2446,43 @@ dependencies = [ ] [[package]] -name = "temporal-sdk-core" +name = "temporalio-common" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "base64", + "derive_builder", + "derive_more", + "opentelemetry", + "prost", + "prost-wkt", + "prost-wkt-types", + "rand 0.9.2", + "serde", + "serde_json", + "thiserror 2.0.14", + "tonic", + "tonic-prost", + "tonic-prost-build", + "tracing", + "tracing-core", + "url", + "uuid", +] + +[[package]] +name = "temporalio-macros" +version = "0.1.0" +dependencies = [ + "derive_more", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "temporalio-sdk-core" version = "0.1.0" dependencies = [ "anyhow", @@ -2479,16 +2518,15 @@ dependencies = [ "rand 0.9.2", "reqwest", "ringbuf", - "rustfsm", "serde", "serde_json", "siphasher", "slotmap", "sysinfo", "tar", - "temporal-client", - "temporal-sdk-core-api", - "temporal-sdk-core-protos", + "temporalio-client", + "temporalio-common", + "temporalio-macros", "thiserror 2.0.14", "tokio", "tokio-stream", @@ -2501,71 +2539,6 @@ dependencies = [ "zip", ] -[[package]] -name = "temporal-sdk-core-api" -version = "0.1.0" -dependencies = [ - "async-trait", - "derive_builder", - "derive_more", - "opentelemetry", - "prost", - "serde_json", - "temporal-sdk-core-protos", - "thiserror 2.0.14", - "tonic", - "tracing", - "tracing-core", - "url", - "uuid", -] - -[[package]] -name = "temporal-sdk-core-protos" -version = "0.1.0" -dependencies = [ - "anyhow", - "base64", - "derive_more", - "prost", - "prost-wkt", - "prost-wkt-types", - "rand 0.9.2", - "serde", - "serde_json", - "thiserror 2.0.14", - "tonic", - "tonic-prost", - "tonic-prost-build", - "uuid", -] - -[[package]] -name = "temporal-sdk-typescript-bridge" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "bridge-macros", - "futures", - "neon", - "opentelemetry", - "os_pipe", - "parking_lot", - "prost", - "prost-types", - "serde", - "serde_json", - "temporal-client", - "temporal-sdk-core", - "thiserror 2.0.14", - "tokio", - "tokio-stream", - "tonic", - "tracing", - "tracing-subscriber", -] - [[package]] name = "termtree" version = "0.5.1" diff --git a/packages/core-bridge/Cargo.toml b/packages/core-bridge/Cargo.toml index ecc4e78e0..41be46b2b 100644 --- a/packages/core-bridge/Cargo.toml +++ b/packages/core-bridge/Cargo.toml @@ -35,10 +35,11 @@ prost = "0.14" prost-types = "0.14" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -temporal-sdk-core = { version = "*", path = "./sdk-core/core", features = [ +temporalio-sdk-core = { version = "*", path = "./sdk-core/crates/sdk-core", features = [ "ephemeral-server", ] } -temporal-client = { version = "*", path = "./sdk-core/client" } +temporalio-client = { version = "*", path = "./sdk-core/crates/client" } +temporalio-common = { version = "*", path = "./sdk-core/crates/common" } thiserror = "2" tokio = "1.13" tokio-stream = "0.1" diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index 9e9a46191..5560b4a0d 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit 9e9a46191656fc9ccd95589dac3552410561d620 +Subproject commit 5560b4a0d4ed94425fd7e4b96328e0b3654e9aee diff --git a/packages/core-bridge/src/client.rs b/packages/core-bridge/src/client.rs index 7b6fc6957..84c035ab3 100644 --- a/packages/core-bridge/src/client.rs +++ b/packages/core-bridge/src/client.rs @@ -5,10 +5,10 @@ use std::{collections::HashMap, sync::Arc}; use neon::prelude::*; use tonic::metadata::{BinaryMetadataValue, MetadataKey}; -use temporal_sdk_core::{ClientOptions as CoreClientOptions, CoreRuntime, RetryClient}; +use temporalio_sdk_core::{ClientOptions as CoreClientOptions, CoreRuntime, RetryClient}; use bridge_macros::{TryFromJs, js_function}; -use temporal_client::{ClientInitError, ConfiguredClient, TemporalServiceClient}; +use temporalio_client::{ClientInitError, ConfiguredClient, TemporalServiceClient}; use crate::runtime::Runtime; use crate::{helpers::*, runtime::RuntimeExt as _}; @@ -257,7 +257,7 @@ async fn client_invoke_workflow_service( mut retry_client: CoreClient, call: RpcCall, ) -> BridgeResult> { - use temporal_client::WorkflowService; + use temporalio_client::WorkflowService; match call.rpc.as_str() { "CountWorkflowExecutions" => { @@ -522,7 +522,7 @@ async fn client_invoke_operator_service( mut retry_client: CoreClient, call: RpcCall, ) -> BridgeResult> { - use temporal_client::OperatorService; + use temporalio_client::OperatorService; match call.rpc.as_str() { "AddOrUpdateRemoteCluster" => { @@ -560,7 +560,7 @@ async fn client_invoke_test_service( mut retry_client: CoreClient, call: RpcCall, ) -> BridgeResult> { - use temporal_client::TestService; + use temporalio_client::TestService; match call.rpc.as_str() { "GetCurrentTime" => rpc_call!(retry_client, call, get_current_time), @@ -582,7 +582,7 @@ async fn client_invoke_health_service( mut retry_client: CoreClient, call: RpcCall, ) -> BridgeResult> { - use temporal_client::HealthService; + use temporalio_client::HealthService; match call.rpc.as_str() { "Check" => rpc_call!(retry_client, call, check), @@ -652,8 +652,8 @@ mod config { use anyhow::Context as _; - use temporal_client::HttpConnectProxyOptions; - use temporal_sdk_core::{ + use temporalio_client::HttpConnectProxyOptions; + use temporalio_sdk_core::{ ClientOptions as CoreClientOptions, ClientOptionsBuilder, ClientTlsConfig as CoreClientTlsConfig, TlsConfig as CoreTlsConfig, Url, }; diff --git a/packages/core-bridge/src/helpers/try_from_js.rs b/packages/core-bridge/src/helpers/try_from_js.rs index 472ad2010..62e6aff11 100644 --- a/packages/core-bridge/src/helpers/try_from_js.rs +++ b/packages/core-bridge/src/helpers/try_from_js.rs @@ -9,7 +9,7 @@ use neon::{ Value, buffer::TypedArray, }, }; -use temporal_sdk_core::Url; +use temporalio_sdk_core::Url; use super::{AppendFieldContext, BridgeError, BridgeResult}; diff --git a/packages/core-bridge/src/logs.rs b/packages/core-bridge/src/logs.rs index 694d3c7e2..dc8ecc485 100644 --- a/packages/core-bridge/src/logs.rs +++ b/packages/core-bridge/src/logs.rs @@ -6,7 +6,7 @@ use std::{ use neon::prelude::*; use serde::{Serialize, ser::SerializeMap as _}; -use temporal_sdk_core::api::telemetry::CoreLog; +use temporalio_common::telemetry::CoreLog; use bridge_macros::js_function; diff --git a/packages/core-bridge/src/metrics.rs b/packages/core-bridge/src/metrics.rs index b4831043b..d03c71ed8 100644 --- a/packages/core-bridge/src/metrics.rs +++ b/packages/core-bridge/src/metrics.rs @@ -4,14 +4,14 @@ use anyhow::Context as _; use neon::prelude::*; use serde::Deserialize; -use temporal_sdk_core::api::telemetry::metrics::{ +use temporalio_common::telemetry::metrics::{ CoreMeter, Counter as CoreCounter, Gauge as CoreGauge, Histogram as CoreHistogram, MetricParametersBuilder, NewAttributes, TemporalMeter, }; -use temporal_sdk_core::api::telemetry::metrics::{ +use temporalio_common::telemetry::metrics::{ GaugeF64 as CoreGaugeF64, HistogramF64 as CoreHistogramF64, }; -use temporal_sdk_core::api::telemetry::metrics::{ +use temporalio_common::telemetry::metrics::{ MetricKeyValue as CoreMetricKeyValue, MetricValue as CoreMetricValue, }; diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index d54a16444..9ead0b9d1 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -5,12 +5,12 @@ use futures::channel::mpsc::Receiver; use neon::prelude::*; use tracing::{Instrument, warn}; -use temporal_sdk_core::{ +use temporalio_common::telemetry::{ + CoreLog, OtelCollectorOptions as CoreOtelCollectorOptions, + PrometheusExporterOptions as CorePrometheusExporterOptions, metrics::CoreMeter, +}; +use temporalio_sdk_core::{ CoreRuntime, RuntimeOptionsBuilder, TokioRuntimeBuilder, - api::telemetry::{ - CoreLog, OtelCollectorOptions as CoreOtelCollectorOptions, - PrometheusExporterOptions as CorePrometheusExporterOptions, metrics::CoreMeter, - }, telemetry::{build_otlp_metric_exporter, start_prometheus_metric_exporter}, }; @@ -241,17 +241,14 @@ mod config { use anyhow::Context as _; use neon::prelude::*; - use temporal_sdk_core::{ - Url, - api::telemetry::{ - HistogramBucketOverrides, Logger as CoreTelemetryLogger, MetricTemporality, - OtelCollectorOptions as CoreOtelCollectorOptions, OtelCollectorOptionsBuilder, - OtlpProtocol, PrometheusExporterOptions as CorePrometheusExporterOptions, - PrometheusExporterOptionsBuilder, TelemetryOptions as CoreTelemetryOptions, - TelemetryOptionsBuilder, - }, - telemetry::CoreLogStreamConsumer, + use temporalio_common::telemetry::{ + HistogramBucketOverrides, Logger as CoreTelemetryLogger, MetricTemporality, + OtelCollectorOptions as CoreOtelCollectorOptions, OtelCollectorOptionsBuilder, + OtlpProtocol, PrometheusExporterOptions as CorePrometheusExporterOptions, + PrometheusExporterOptionsBuilder, TelemetryOptions as CoreTelemetryOptions, + TelemetryOptionsBuilder, }; + use temporalio_sdk_core::{Url, telemetry::CoreLogStreamConsumer}; use bridge_macros::TryFromJs; diff --git a/packages/core-bridge/src/testing.rs b/packages/core-bridge/src/testing.rs index 6be02eebf..c7c02049e 100644 --- a/packages/core-bridge/src/testing.rs +++ b/packages/core-bridge/src/testing.rs @@ -4,13 +4,13 @@ use std::{process::Stdio, sync::Arc}; use anyhow::Context as _; use neon::prelude::*; -use temporal_sdk_core::ephemeral_server::{ +use temporalio_sdk_core::ephemeral_server::{ EphemeralServer as CoreEphemeralServer, TemporalDevServerConfig as CoreTemporalDevServerConfig, TestServerConfig as CoreTestServerConfig, }; use bridge_macros::js_function; -use temporal_sdk_core::CoreRuntime; +use temporalio_sdk_core::CoreRuntime; use crate::helpers::*; use crate::runtime::{Runtime, RuntimeExt as _}; @@ -191,7 +191,7 @@ mod config { use anyhow::Context as _; - use temporal_sdk_core::ephemeral_server::{ + use temporalio_sdk_core::ephemeral_server::{ EphemeralExe, EphemeralExeVersion, TemporalDevServerConfig as CoreTemporalDevServerConfig, TemporalDevServerConfigBuilder, TestServerConfig as CoreTestServerConfig, TestServerConfigBuilder, diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index f92184f41..d0d0cdff3 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -6,20 +6,19 @@ use prost::Message; use tokio::sync::mpsc::{Sender, channel}; use tokio_stream::wrappers::ReceiverStream; -use temporal_sdk_core::{ - CoreRuntime, - api::{ - Worker as CoreWorkerTrait, - errors::{CompleteActivityError, CompleteNexusError, CompleteWfError, PollError}, - }, - init_replay_worker, init_worker, - protos::{ - coresdk::{ - ActivityHeartbeat, ActivityTaskCompletion, nexus::NexusTaskCompletion, - workflow_completion::WorkflowActivationCompletion, - }, - temporal::api::history::v1::History, +use temporalio_common::Worker as CoreWorkerTrait; +use temporalio_common::errors::{ + CompleteActivityError, CompleteNexusError, CompleteWfError, PollError, +}; +use temporalio_common::protos::{ + coresdk::{ + ActivityHeartbeat, ActivityTaskCompletion, nexus::NexusTaskCompletion, + workflow_completion::WorkflowActivationCompletion, }, + temporal::api::history::v1::History, +}; +use temporalio_sdk_core::{ + CoreRuntime, init_replay_worker, init_worker, replay::{HistoryForReplay, ReplayWorkerInput}, }; @@ -70,7 +69,7 @@ pub struct Worker { core_runtime: Arc, // Arc so that we can send reference into async closures - core_worker: Arc, + core_worker: Arc, } /// Create a new worker. @@ -466,16 +465,16 @@ impl MutableFinalize for HistoryForReplayTunnelHandle {} mod config { use std::{sync::Arc, time::Duration}; - use temporal_sdk_core::{ + use temporalio_common::protos::temporal::api::enums::v1::VersioningBehavior as CoreVersioningBehavior; + use temporalio_common::worker::{ + ActivitySlotKind, LocalActivitySlotKind, NexusSlotKind, + PollerBehavior as CorePollerBehavior, SlotKind, WorkerConfig, WorkerConfigBuilder, + WorkerConfigBuilderError, WorkerDeploymentOptions as CoreWorkerDeploymentOptions, + WorkerDeploymentVersion as CoreWorkerDeploymentVersion, WorkflowSlotKind, + }; + use temporalio_sdk_core::{ ResourceBasedSlotsOptions, ResourceBasedSlotsOptionsBuilder, ResourceSlotOptions, SlotSupplierOptions as CoreSlotSupplierOptions, TunerHolder, TunerHolderOptionsBuilder, - api::worker::{ - ActivitySlotKind, LocalActivitySlotKind, NexusSlotKind, - PollerBehavior as CorePollerBehavior, SlotKind, WorkerConfig, WorkerConfigBuilder, - WorkerConfigBuilderError, WorkerDeploymentOptions as CoreWorkerDeploymentOptions, - WorkerDeploymentVersion as CoreWorkerDeploymentVersion, WorkflowSlotKind, - }, - protos::temporal::api::enums::v1::VersioningBehavior as CoreVersioningBehavior, }; use super::custom_slot_supplier::CustomSlotSupplierOptions; @@ -485,7 +484,7 @@ mod config { use neon::object::Object; use neon::prelude::JsResult; use neon::types::JsObject; - use temporal_sdk_core::api::worker::WorkerVersioningStrategy; + use temporalio_common::worker::WorkerVersioningStrategy; #[derive(TryFromJs)] pub struct BridgeWorkerOptions { @@ -749,16 +748,14 @@ mod custom_slot_supplier { use neon::{context::Context, handle::Handle, prelude::*}; - use temporal_sdk_core::{ - SlotSupplierOptions as CoreSlotSupplierOptions, - api::worker::{ - SlotInfo as CoreSlotInfo, SlotInfoTrait as _, SlotKind, - SlotKindType as CoreSlotKindType, SlotMarkUsedContext as CoreSlotMarkUsedContext, - SlotReleaseContext as CoreSlotReleaseContext, - SlotReservationContext as CoreSlotReservationContext, SlotSupplier as CoreSlotSupplier, - SlotSupplierPermit as CoreSlotSupplierPermit, - }, + use temporalio_common::worker::{ + SlotInfo as CoreSlotInfo, SlotInfoTrait as _, SlotKind, SlotKindType as CoreSlotKindType, + SlotMarkUsedContext as CoreSlotMarkUsedContext, + SlotReleaseContext as CoreSlotReleaseContext, + SlotReservationContext as CoreSlotReservationContext, SlotSupplier as CoreSlotSupplier, + SlotSupplierPermit as CoreSlotSupplierPermit, }; + use temporalio_sdk_core::SlotSupplierOptions as CoreSlotSupplierOptions; use bridge_macros::{TryFromJs, TryIntoJs}; use tracing::warn; diff --git a/packages/proto/scripts/compile-proto.js b/packages/proto/scripts/compile-proto.js index 5c11a70ae..ea86ef355 100644 --- a/packages/proto/scripts/compile-proto.js +++ b/packages/proto/scripts/compile-proto.js @@ -10,7 +10,7 @@ const outputDir = resolve(__dirname, '../protos'); const jsOutputFile = resolve(outputDir, 'json-module.js'); const tempFile = resolve(outputDir, 'temp.js'); -const protoBaseDir = resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos'); +const protoBaseDir = resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos'); function mtime(path) { try { From d908b7b9339ecfd6c4918ef2fefbc98ac403a563 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 13:09:43 -0400 Subject: [PATCH 03/18] add skipClientWorkerSetCheck to worker options --- packages/core-bridge/src/worker.rs | 2 ++ packages/core-bridge/ts/native.ts | 1 + packages/test/src/test-bridge.ts | 1 + packages/test/src/test-integration-workflows.ts | 2 ++ packages/test/src/test-sinks.ts | 6 ++++++ packages/test/src/test-worker-deployment-versioning.ts | 5 +++++ packages/worker/src/worker-options.ts | 8 ++++++++ 7 files changed, 25 insertions(+) diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index d0d0cdff3..a2a599d56 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -507,6 +507,7 @@ mod config { max_activities_per_second: Option, max_task_queue_activities_per_second: Option, shutdown_grace_time: Option, + skip_client_worker_set_check: bool, } #[derive(TryFromJs)] @@ -574,6 +575,7 @@ mod config { .max_task_queue_activities_per_second(self.max_task_queue_activities_per_second) .max_worker_activities_per_second(self.max_activities_per_second) .graceful_shutdown_period(self.shutdown_grace_time) + .skip_client_worker_set_check(self.skip_client_worker_set_check) .build() } } diff --git a/packages/core-bridge/ts/native.ts b/packages/core-bridge/ts/native.ts index 2ddd20a1c..04c166f4b 100644 --- a/packages/core-bridge/ts/native.ts +++ b/packages/core-bridge/ts/native.ts @@ -221,6 +221,7 @@ export interface WorkerOptions { maxTaskQueueActivitiesPerSecond: Option; maxActivitiesPerSecond: Option; shutdownGraceTime: number; + skipClientWorkerSetCheck: boolean; } export type PollerBehavior = diff --git a/packages/test/src/test-bridge.ts b/packages/test/src/test-bridge.ts index df14e0183..6ba7036cb 100644 --- a/packages/test/src/test-bridge.ts +++ b/packages/test/src/test-bridge.ts @@ -306,6 +306,7 @@ const GenericConfigs = { maxTaskQueueActivitiesPerSecond: null, maxActivitiesPerSecond: null, shutdownGraceTime: 1000, + skipClientWorkerSetCheck: true, } satisfies native.WorkerOptions, }, ephemeralServer: { diff --git a/packages/test/src/test-integration-workflows.ts b/packages/test/src/test-integration-workflows.ts index 3b0604d17..8de6268ba 100644 --- a/packages/test/src/test-integration-workflows.ts +++ b/packages/test/src/test-integration-workflows.ts @@ -459,6 +459,7 @@ test('Worker requests Eager Activity Dispatch if possible', async (t) => { activities: { testActivity: () => 'workflow-and-activity-worker', }, + skipClientWorkerSetCheck: true, }); const handle = await startWorkflow(executeEagerActivity); await activityWorker.runUntil(workflowWorker.runUntil(handle.result())); @@ -495,6 +496,7 @@ test("Worker doesn't request Eager Activity Dispatch if no activities are regist }); const workflowWorker = await createWorker({ activities: {}, + skipClientWorkerSetCheck: true, }); const handle = await startWorkflow(dontExecuteEagerActivity); const result = await activityWorker.runUntil(workflowWorker.runUntil(handle.result())); diff --git a/packages/test/src/test-sinks.ts b/packages/test/src/test-sinks.ts index a7ed18b88..735922657 100644 --- a/packages/test/src/test-sinks.ts +++ b/packages/test/src/test-sinks.ts @@ -261,6 +261,7 @@ if (RUN_INTEGRATION_TESTS) { sinks, maxCachedWorkflows: 0, maxConcurrentWorkflowTaskExecutions: 2, + skipClientWorkerSetCheck: true, }); const client = new WorkflowClient(); await worker.runUntil(client.execute(workflows.logSinkTester, { taskQueue, workflowId: uuid4() })); @@ -307,6 +308,7 @@ if (RUN_INTEGRATION_TESTS) { ...defaultOptions, taskQueue, sinks, + skipClientWorkerSetCheck: true, }); const workflowId = uuid4(); await worker.runUntil(client.execute(workflows.logSinkTester, { taskQueue, workflowId })); @@ -320,6 +322,7 @@ if (RUN_INTEGRATION_TESTS) { { ...defaultOptions, sinks, + skipClientWorkerSetCheck: true, }, history, workflowId @@ -351,6 +354,7 @@ if (RUN_INTEGRATION_TESTS) { ...defaultOptions, taskQueue, sinks, + skipClientWorkerSetCheck: true, }); const client = new WorkflowClient(); const workflowId = uuid4(); @@ -367,6 +371,7 @@ if (RUN_INTEGRATION_TESTS) { { ...defaultOptions, sinks, + skipClientWorkerSetCheck: true, }, history, workflowId @@ -411,6 +416,7 @@ if (RUN_INTEGRATION_TESTS) { ...defaultOptions, taskQueue, sinks, + skipClientWorkerSetCheck: true, }); await worker.runUntil( client.execute(workflows.upsertAndReadSearchAttributes, { diff --git a/packages/test/src/test-worker-deployment-versioning.ts b/packages/test/src/test-worker-deployment-versioning.ts index fdac331cc..be0025619 100644 --- a/packages/test/src/test-worker-deployment-versioning.ts +++ b/packages/test/src/test-worker-deployment-versioning.ts @@ -43,6 +43,7 @@ test('Worker deployment based versioning', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, + skipClientWorkerSetCheck: true, }); const worker1Promise = worker1.run(); worker1Promise.catch((err) => { @@ -58,6 +59,7 @@ test('Worker deployment based versioning', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, + skipClientWorkerSetCheck: true, }); const worker2Promise = worker2.run(); worker2Promise.catch((err) => { @@ -73,6 +75,7 @@ test('Worker deployment based versioning', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, + skipClientWorkerSetCheck: true, }); const worker3Promise = worker3.run(); worker3Promise.catch((err) => { @@ -160,6 +163,7 @@ test('Worker deployment based versioning with ramping', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, + skipClientWorkerSetCheck: true, }); const worker1Promise = worker1.run(); worker1Promise.catch((err) => { @@ -175,6 +179,7 @@ test('Worker deployment based versioning with ramping', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, + skipClientWorkerSetCheck: true, }); const worker2Promise = worker2.run(); worker2Promise.catch((err) => { diff --git a/packages/worker/src/worker-options.ts b/packages/worker/src/worker-options.ts index c3e56aa49..636e5a013 100644 --- a/packages/worker/src/worker-options.ts +++ b/packages/worker/src/worker-options.ts @@ -464,6 +464,11 @@ export interface WorkerOptions { */ defaultHeartbeatThrottleInterval?: Duration; + /** + * TODO: write + */ + skipClientWorkerSetCheck?: boolean; + /** * A mapping of interceptor type to a list of factories or module paths. * @@ -817,6 +822,7 @@ export type WorkerOptionsWithDefaults = WorkerOptions & | 'debugMode' | 'reuseV8Context' | 'tuner' + | 'skipClientWorkerSetCheck' > > & { interceptors: Required; @@ -968,6 +974,7 @@ function addDefaultWorkerOptions( stickyQueueScheduleToStartTimeout: '10s', maxHeartbeatThrottleInterval: '60s', defaultHeartbeatThrottleInterval: '30s', + skipClientWorkerSetCheck: false, // 4294967295ms is the maximum allowed time isolateExecutionTimeout: debugMode ? '4294967295ms' : '5s', workflowThreadPoolSize: reuseV8Context ? 1 : 2, @@ -1084,6 +1091,7 @@ export function toNativeWorkerOptions(opts: CompiledWorkerOptionsWithBuildId): n maxTaskQueueActivitiesPerSecond: opts.maxTaskQueueActivitiesPerSecond ?? null, maxActivitiesPerSecond: opts.maxActivitiesPerSecond ?? null, shutdownGraceTime: msToNumber(opts.shutdownGraceTime), + skipClientWorkerSetCheck: opts.skipClientWorkerSetCheck, }; } From c3960b337bf1dee28066f0e82ef94ab556ee64ca Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 13:49:29 -0400 Subject: [PATCH 04/18] update workflow poller assertion --- packages/test/src/test-worker-poller-autoscale.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/test/src/test-worker-poller-autoscale.ts b/packages/test/src/test-worker-poller-autoscale.ts index edd96c8b9..669255066 100644 --- a/packages/test/src/test-worker-poller-autoscale.ts +++ b/packages/test/src/test-worker-poller-autoscale.ts @@ -48,7 +48,7 @@ test.serial('Can run autoscaling polling worker', async (t) => { const activity_pollers = matches.filter((l) => l.includes('activity_task')); t.is(activity_pollers.length, 1, 'Should have exactly one activity poller metric'); t.true(activity_pollers[0].endsWith('2'), 'Activity poller count should be 2'); - const workflow_pollers = matches.filter((l) => l.includes('workflow_task')); + const workflow_pollers = matches.filter((l) => l.includes('workflow_task') && l.includes(taskQueue)); t.is(workflow_pollers.length, 2, 'Should have exactly two workflow poller metrics (sticky and non-sticky)'); // There's sticky & non-sticky pollers, and they may have a count of 1 or 2 depending on From 400e7b76f07dab1e8040259b92ea8481c2d570be Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 15:30:24 -0400 Subject: [PATCH 05/18] chore: update filter string with new crate names --- packages/core-bridge/src/runtime.rs | 14 ++++++-------- packages/worker/src/runtime-options.ts | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index 9ead0b9d1..211e3bea1 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -62,14 +62,12 @@ pub fn runtime_new( let (telemetry_options, metrics_options, logging_options) = bridge_options.try_into()?; // Create core runtime which starts tokio multi-thread runtime - let mut core_runtime = CoreRuntime::new( - RuntimeOptionsBuilder::default() - .telemetry_options(telemetry_options) - .build() - .expect("RuntimeOptionsBuilder to never fail as every field has a default"), - TokioRuntimeBuilder::default(), - ) - .context("Failed to initialize Core Runtime")?; + let runtime_options = RuntimeOptionsBuilder::default() + .telemetry_options(telemetry_options) + .build() + .context("Failed to build runtime options")?; + let mut core_runtime = CoreRuntime::new(runtime_options, TokioRuntimeBuilder::default()) + .context("Failed to initialize Core Runtime")?; enter_sync!(core_runtime); diff --git a/packages/worker/src/runtime-options.ts b/packages/worker/src/runtime-options.ts index b92ad017e..d38db5a87 100644 --- a/packages/worker/src/runtime-options.ts +++ b/packages/worker/src/runtime-options.ts @@ -468,7 +468,7 @@ export type MakeTelemetryFilterStringOptions = CoreLogFilterOptions; */ export function makeTelemetryFilterString(options: CoreLogFilterOptions): string { const { core, other } = options; - return `${other ?? 'ERROR'},temporal_sdk_core=${core},temporal_client=${core},temporal_sdk=${core}`; + return `${other ?? 'ERROR'},temporalio_sdk_core=${core},temporalio_client=${core},temporalio_common=${core}`; } function isOtelCollectorExporter(metrics: MetricsExporterConfig): metrics is OtelCollectorExporter { From a7fefda1d232ee5820c1a34f725251c6740cf7dd Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 15:51:51 -0400 Subject: [PATCH 06/18] update proto paths --- packages/test/src/test-client-connection.ts | 6 +++--- .../test/src/test-native-connection-headers.ts | 8 ++++---- packages/test/src/test-native-connection.ts | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/test/src/test-client-connection.ts b/packages/test/src/test-client-connection.ts index 7545c916a..62ab08700 100644 --- a/packages/test/src/test-client-connection.ts +++ b/packages/test/src/test-client-connection.ts @@ -22,14 +22,14 @@ import { temporal, grpc as grpcProto } from '@temporalio/proto'; const workflowServicePackageDefinition = protoLoader.loadSync( path.resolve( __dirname, - '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' + '../../core-bridge/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' ), - { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream')] } + { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/api_upstream')] } ); const workflowServiceProtoDescriptor = grpc.loadPackageDefinition(workflowServicePackageDefinition) as any; const healthServicePackageDefinition = protoLoader.loadSync( - path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/grpc/health/v1/health.proto') + path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/grpc/health/v1/health.proto') ); const healthServicePackageDescriptor = grpc.loadPackageDefinition(healthServicePackageDefinition) as any; diff --git a/packages/test/src/test-native-connection-headers.ts b/packages/test/src/test-native-connection-headers.ts index db466930d..5f4f739f8 100644 --- a/packages/test/src/test-native-connection-headers.ts +++ b/packages/test/src/test-native-connection-headers.ts @@ -12,9 +12,9 @@ import { Worker } from './helpers'; const workflowServicePackageDefinition = protoLoader.loadSync( path.resolve( __dirname, - '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' + '../../core-bridge/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' ), - { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream')] } + { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/api_upstream')] } ); const workflowServiceProtoDescriptor = grpc.loadPackageDefinition(workflowServicePackageDefinition) as any; @@ -26,9 +26,9 @@ test('NativeConnection passes headers provided in options', async (t) => { const packageDefinition = protoLoader.loadSync( path.resolve( __dirname, - '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' + '../../core-bridge/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' ), - { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream')] } + { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/api_upstream')] } ); const protoDescriptor = grpc.loadPackageDefinition(packageDefinition) as any; diff --git a/packages/test/src/test-native-connection.ts b/packages/test/src/test-native-connection.ts index 4eabf99ed..8d8e5d1ff 100644 --- a/packages/test/src/test-native-connection.ts +++ b/packages/test/src/test-native-connection.ts @@ -15,23 +15,23 @@ import { RUN_INTEGRATION_TESTS, Worker } from './helpers'; const workflowServicePackageDefinition = protoLoader.loadSync( path.resolve( __dirname, - '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' + '../../core-bridge/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto' ), - { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream')] } + { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/api_upstream')] } ); const workflowServiceProtoDescriptor = grpc.loadPackageDefinition(workflowServicePackageDefinition) as any; const operatorServicePackageDefinition = protoLoader.loadSync( path.resolve( __dirname, - '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto' + '../../core-bridge/sdk-core/crates/common/protos/api_upstream/temporal/api/operatorservice/v1/service.proto' ), - { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/api_upstream')] } + { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/api_upstream')] } ); const operatorServiceProtoDescriptor = grpc.loadPackageDefinition(operatorServicePackageDefinition) as any; const healthServicePackageDefinition = protoLoader.loadSync( - path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/grpc/health/v1/health.proto'), + path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/grpc/health/v1/health.proto'), { includeDirs: [] } ); const healthServiceProtoDescriptor = grpc.loadPackageDefinition(healthServicePackageDefinition) as any; @@ -39,9 +39,9 @@ const healthServiceProtoDescriptor = grpc.loadPackageDefinition(healthServicePac const testServicePackageDefinition = protoLoader.loadSync( path.resolve( __dirname, - '../../core-bridge/sdk-core/sdk-core-protos/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto' + '../../core-bridge/sdk-core/crates/common/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto' ), - { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/sdk-core-protos/protos/testsrv_upstream')] } + { includeDirs: [path.resolve(__dirname, '../../core-bridge/sdk-core/crates/common/protos/testsrv_upstream')] } ); const testServiceProtoDescriptor = grpc.loadPackageDefinition(testServicePackageDefinition) as any; From 8e19b60f8cbcb7716d740c560890ca44aa0646bf Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 16:05:00 -0400 Subject: [PATCH 07/18] add new workflow service rpc calls --- packages/core-bridge/src/client.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/core-bridge/src/client.rs b/packages/core-bridge/src/client.rs index 84c035ab3..c427ccfb1 100644 --- a/packages/core-bridge/src/client.rs +++ b/packages/core-bridge/src/client.rs @@ -290,6 +290,9 @@ async fn client_invoke_workflow_service( "DescribeDeployment" => { rpc_call!(retry_client, call, describe_deployment) } + "DescribeWorker" => { + rpc_call!(retry_client, call, describe_worker) + } "DeprecateNamespace" => rpc_call!(retry_client, call, deprecate_namespace), "DescribeNamespace" => rpc_call!(retry_client, call, describe_namespace), "DescribeSchedule" => rpc_call!(retry_client, call, describe_schedule), @@ -450,6 +453,9 @@ async fn client_invoke_workflow_service( "SetWorkerDeploymentCurrentVersion" => { rpc_call!(retry_client, call, set_worker_deployment_current_version) } + "SetWorkerDeploymentManager" => { + rpc_call!(retry_client, call, set_worker_deployment_manager) + } "SetWorkerDeploymentRampingVersion" => { rpc_call!(retry_client, call, set_worker_deployment_ramping_version) } From 479e5e2e474006b438c4d41e800190869dbe6b55 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Thu, 23 Oct 2025 16:40:44 -0400 Subject: [PATCH 08/18] write doc comment --- packages/worker/src/worker-options.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/worker/src/worker-options.ts b/packages/worker/src/worker-options.ts index 636e5a013..783f47198 100644 --- a/packages/worker/src/worker-options.ts +++ b/packages/worker/src/worker-options.ts @@ -465,7 +465,10 @@ export interface WorkerOptions { defaultHeartbeatThrottleInterval?: Duration; /** - * TODO: write + * Skip the runtime validation that ensures the client is registered with the worker set. + * This should only be used in tests. + * + * @default false */ skipClientWorkerSetCheck?: boolean; From 297ecd85ec8446f969a8a17b19ecdc0563b273a6 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Fri, 24 Oct 2025 16:03:39 -0400 Subject: [PATCH 09/18] remove public config setting --- packages/core-bridge/Cargo.lock | 1 + packages/core-bridge/sdk-core | 2 +- packages/core-bridge/src/worker.rs | 2 -- packages/core-bridge/ts/native.ts | 1 - packages/test/src/helpers-integration.ts | 6 ++++++ packages/test/src/test-bridge.ts | 1 - .../test/src/test-integration-workflows.ts | 14 +++++++++---- packages/test/src/test-sinks.ts | 6 ------ .../src/test-worker-deployment-versioning.ts | 21 +++++++++++-------- packages/worker/src/worker-options.ts | 11 ---------- 10 files changed, 30 insertions(+), 35 deletions(-) diff --git a/packages/core-bridge/Cargo.lock b/packages/core-bridge/Cargo.lock index b92fc0455..0fb1f9b6e 100644 --- a/packages/core-bridge/Cargo.lock +++ b/packages/core-bridge/Cargo.lock @@ -2434,6 +2434,7 @@ dependencies = [ "hyper", "hyper-util", "parking_lot", + "rand 0.9.2", "slotmap", "temporalio-common", "thiserror 2.0.14", diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index 5560b4a0d..da2028d86 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit 5560b4a0d4ed94425fd7e4b96328e0b3654e9aee +Subproject commit da2028d86fc35eb28037045342a68f134824f186 diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index a2a599d56..d0d0cdff3 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -507,7 +507,6 @@ mod config { max_activities_per_second: Option, max_task_queue_activities_per_second: Option, shutdown_grace_time: Option, - skip_client_worker_set_check: bool, } #[derive(TryFromJs)] @@ -575,7 +574,6 @@ mod config { .max_task_queue_activities_per_second(self.max_task_queue_activities_per_second) .max_worker_activities_per_second(self.max_activities_per_second) .graceful_shutdown_period(self.shutdown_grace_time) - .skip_client_worker_set_check(self.skip_client_worker_set_check) .build() } } diff --git a/packages/core-bridge/ts/native.ts b/packages/core-bridge/ts/native.ts index 04c166f4b..2ddd20a1c 100644 --- a/packages/core-bridge/ts/native.ts +++ b/packages/core-bridge/ts/native.ts @@ -221,7 +221,6 @@ export interface WorkerOptions { maxTaskQueueActivitiesPerSecond: Option; maxActivitiesPerSecond: Option; shutdownGraceTime: number; - skipClientWorkerSetCheck: boolean; } export type PollerBehavior = diff --git a/packages/test/src/helpers-integration.ts b/packages/test/src/helpers-integration.ts index 9d0d6fab0..0b5379627 100644 --- a/packages/test/src/helpers-integration.ts +++ b/packages/test/src/helpers-integration.ts @@ -17,6 +17,8 @@ import { DefaultLogger, LogEntry, LogLevel, + NativeConnection, + NativeConnectionOptions, ReplayWorkerOptions, Runtime, RuntimeOptions, @@ -184,6 +186,7 @@ export async function createTestWorkflowEnvironment( export interface Helpers { taskQueue: string; createWorker(opts?: Partial): Promise; + createNativeConnection(opts?: Partial): Promise; runReplayHistory(opts: Partial, history: temporal.api.history.v1.IHistory): Promise; executeWorkflow Promise>(workflowType: T): Promise>; executeWorkflow( @@ -218,6 +221,9 @@ export function configurableHelpers( ...opts, }); }, + async createNativeConnection(opts?: Partial): Promise { + return await NativeConnection.connect({ address: testEnv.address, ...opts }); + }, async runReplayHistory( opts: Partial, history: temporal.api.history.v1.IHistory diff --git a/packages/test/src/test-bridge.ts b/packages/test/src/test-bridge.ts index 6ba7036cb..df14e0183 100644 --- a/packages/test/src/test-bridge.ts +++ b/packages/test/src/test-bridge.ts @@ -306,7 +306,6 @@ const GenericConfigs = { maxTaskQueueActivitiesPerSecond: null, maxActivitiesPerSecond: null, shutdownGraceTime: 1000, - skipClientWorkerSetCheck: true, } satisfies native.WorkerOptions, }, ephemeralServer: { diff --git a/packages/test/src/test-integration-workflows.ts b/packages/test/src/test-integration-workflows.ts index 8de6268ba..c75d3a33b 100644 --- a/packages/test/src/test-integration-workflows.ts +++ b/packages/test/src/test-integration-workflows.ts @@ -441,7 +441,7 @@ export async function executeEagerActivity(): Promise { } test('Worker requests Eager Activity Dispatch if possible', async (t) => { - const { createWorker, startWorkflow } = helpers(t); + const { createWorker, startWorkflow, createNativeConnection } = helpers(t); // If eager activity dispatch is working, then the task will always be dispatched to the workflow // worker. Otherwise, chances are 50%-50% for either workers. The test workflow schedule the @@ -455,11 +455,15 @@ test('Worker requests Eager Activity Dispatch if possible', async (t) => { // Override the default workflow bundle, to make this an activity-only worker workflowBundle: undefined, }); + const workflowWorkerConnection = await createNativeConnection(); + t.teardown(() => { + workflowWorkerConnection.close(); + }); const workflowWorker = await createWorker({ + connection: workflowWorkerConnection, activities: { testActivity: () => 'workflow-and-activity-worker', }, - skipClientWorkerSetCheck: true, }); const handle = await startWorkflow(executeEagerActivity); await activityWorker.runUntil(workflowWorker.runUntil(handle.result())); @@ -479,7 +483,7 @@ export async function dontExecuteEagerActivity(): Promise { } test("Worker doesn't request Eager Activity Dispatch if no activities are registered", async (t) => { - const { createWorker, startWorkflow } = helpers(t); + const { createNativeConnection, createWorker, startWorkflow } = helpers(t); // If the activity was eagerly dispatched to the Workflow worker even though it is a Workflow-only // worker, then the activity execution will timeout (because tasks are not being polled) or @@ -494,9 +498,11 @@ test("Worker doesn't request Eager Activity Dispatch if no activities are regist // Override the default workflow bundle, to make this an activity-only worker workflowBundle: undefined, }); + const workflowWorkerConnection = await createNativeConnection(); + t.teardown(() => workflowWorkerConnection.close()); const workflowWorker = await createWorker({ + connection: workflowWorkerConnection, activities: {}, - skipClientWorkerSetCheck: true, }); const handle = await startWorkflow(dontExecuteEagerActivity); const result = await activityWorker.runUntil(workflowWorker.runUntil(handle.result())); diff --git a/packages/test/src/test-sinks.ts b/packages/test/src/test-sinks.ts index 735922657..a7ed18b88 100644 --- a/packages/test/src/test-sinks.ts +++ b/packages/test/src/test-sinks.ts @@ -261,7 +261,6 @@ if (RUN_INTEGRATION_TESTS) { sinks, maxCachedWorkflows: 0, maxConcurrentWorkflowTaskExecutions: 2, - skipClientWorkerSetCheck: true, }); const client = new WorkflowClient(); await worker.runUntil(client.execute(workflows.logSinkTester, { taskQueue, workflowId: uuid4() })); @@ -308,7 +307,6 @@ if (RUN_INTEGRATION_TESTS) { ...defaultOptions, taskQueue, sinks, - skipClientWorkerSetCheck: true, }); const workflowId = uuid4(); await worker.runUntil(client.execute(workflows.logSinkTester, { taskQueue, workflowId })); @@ -322,7 +320,6 @@ if (RUN_INTEGRATION_TESTS) { { ...defaultOptions, sinks, - skipClientWorkerSetCheck: true, }, history, workflowId @@ -354,7 +351,6 @@ if (RUN_INTEGRATION_TESTS) { ...defaultOptions, taskQueue, sinks, - skipClientWorkerSetCheck: true, }); const client = new WorkflowClient(); const workflowId = uuid4(); @@ -371,7 +367,6 @@ if (RUN_INTEGRATION_TESTS) { { ...defaultOptions, sinks, - skipClientWorkerSetCheck: true, }, history, workflowId @@ -416,7 +411,6 @@ if (RUN_INTEGRATION_TESTS) { ...defaultOptions, taskQueue, sinks, - skipClientWorkerSetCheck: true, }); await worker.runUntil( client.execute(workflows.upsertAndReadSearchAttributes, { diff --git a/packages/test/src/test-worker-deployment-versioning.ts b/packages/test/src/test-worker-deployment-versioning.ts index be0025619..28b4d15a2 100644 --- a/packages/test/src/test-worker-deployment-versioning.ts +++ b/packages/test/src/test-worker-deployment-versioning.ts @@ -11,7 +11,7 @@ import { Client } from '@temporalio/client'; import { toCanonicalString, WorkerDeploymentVersion } from '@temporalio/common'; import { temporal } from '@temporalio/proto'; import { Worker } from './helpers'; -import { Context, makeTestFunction } from './helpers-integration'; +import { Context, helpers, makeTestFunction } from './helpers-integration'; import { unblockSignal, versionQuery } from './workflows'; const test = makeTestFunction({ workflowsPath: __filename }); @@ -20,6 +20,7 @@ test('Worker deployment based versioning', async (t) => { const taskQueue = 'worker-deployment-based-versioning-' + randomUUID(); const deploymentName = 'deployment-' + randomUUID(); const { client, nativeConnection } = t.context.env; + const { createNativeConnection } = helpers(t); const w1DeploymentVersion = { buildId: '1.0', @@ -43,13 +44,14 @@ test('Worker deployment based versioning', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, - skipClientWorkerSetCheck: true, }); const worker1Promise = worker1.run(); worker1Promise.catch((err) => { t.fail('Worker 1.0 run error: ' + err); }); + const worker2Connection = await createNativeConnection(); + t.teardown(() => worker2Connection.close()); const worker2 = await Worker.create({ workflowsPath: require.resolve('./deployment-versioning-v2'), taskQueue, @@ -58,14 +60,15 @@ test('Worker deployment based versioning', async (t) => { version: w2DeploymentVersion, defaultVersioningBehavior: 'PINNED', }, - connection: nativeConnection, - skipClientWorkerSetCheck: true, + connection: worker2Connection, }); const worker2Promise = worker2.run(); worker2Promise.catch((err) => { t.fail('Worker 2.0 run error: ' + err); }); + const worker3Connection = await createNativeConnection(); + t.teardown(() => worker3Connection.close()); const worker3 = await Worker.create({ workflowsPath: require.resolve('./deployment-versioning-v3'), taskQueue, @@ -74,8 +77,7 @@ test('Worker deployment based versioning', async (t) => { version: w3DeploymentVersion, defaultVersioningBehavior: 'PINNED', }, - connection: nativeConnection, - skipClientWorkerSetCheck: true, + connection: worker3Connection, }); const worker3Promise = worker3.run(); worker3Promise.catch((err) => { @@ -144,6 +146,7 @@ test('Worker deployment based versioning with ramping', async (t) => { const taskQueue = 'worker-deployment-based-ramping-' + randomUUID(); const deploymentName = 'deployment-ramping-' + randomUUID(); const { client, nativeConnection } = t.context.env; + const { createNativeConnection } = helpers(t); const v1 = { buildId: '1.0', @@ -163,13 +166,14 @@ test('Worker deployment based versioning with ramping', async (t) => { defaultVersioningBehavior: 'PINNED', }, connection: nativeConnection, - skipClientWorkerSetCheck: true, }); const worker1Promise = worker1.run(); worker1Promise.catch((err) => { t.fail('Worker 1.0 run error: ' + err); }); + const worker2Connection = await createNativeConnection(); + t.teardown(() => worker2Connection.close()); const worker2 = await Worker.create({ workflowsPath: require.resolve('./deployment-versioning-v2'), taskQueue, @@ -178,8 +182,7 @@ test('Worker deployment based versioning with ramping', async (t) => { version: v2, defaultVersioningBehavior: 'PINNED', }, - connection: nativeConnection, - skipClientWorkerSetCheck: true, + connection: worker2Connection, }); const worker2Promise = worker2.run(); worker2Promise.catch((err) => { diff --git a/packages/worker/src/worker-options.ts b/packages/worker/src/worker-options.ts index 783f47198..c3e56aa49 100644 --- a/packages/worker/src/worker-options.ts +++ b/packages/worker/src/worker-options.ts @@ -464,14 +464,6 @@ export interface WorkerOptions { */ defaultHeartbeatThrottleInterval?: Duration; - /** - * Skip the runtime validation that ensures the client is registered with the worker set. - * This should only be used in tests. - * - * @default false - */ - skipClientWorkerSetCheck?: boolean; - /** * A mapping of interceptor type to a list of factories or module paths. * @@ -825,7 +817,6 @@ export type WorkerOptionsWithDefaults = WorkerOptions & | 'debugMode' | 'reuseV8Context' | 'tuner' - | 'skipClientWorkerSetCheck' > > & { interceptors: Required; @@ -977,7 +968,6 @@ function addDefaultWorkerOptions( stickyQueueScheduleToStartTimeout: '10s', maxHeartbeatThrottleInterval: '60s', defaultHeartbeatThrottleInterval: '30s', - skipClientWorkerSetCheck: false, // 4294967295ms is the maximum allowed time isolateExecutionTimeout: debugMode ? '4294967295ms' : '5s', workflowThreadPoolSize: reuseV8Context ? 1 : 2, @@ -1094,7 +1084,6 @@ export function toNativeWorkerOptions(opts: CompiledWorkerOptionsWithBuildId): n maxTaskQueueActivitiesPerSecond: opts.maxTaskQueueActivitiesPerSecond ?? null, maxActivitiesPerSecond: opts.maxActivitiesPerSecond ?? null, shutdownGraceTime: msToNumber(opts.shutdownGraceTime), - skipClientWorkerSetCheck: opts.skipClientWorkerSetCheck, }; } From 7d52b88cca0072d36ea65550497f4ffc17c07f8e Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Fri, 24 Oct 2025 16:26:39 -0400 Subject: [PATCH 10/18] enable skip validation for replay workers --- packages/core-bridge/src/worker.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index d0d0cdff3..2a15a071e 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -399,9 +399,10 @@ pub fn replay_worker_new( OpaqueOutboundHandle, OpaqueOutboundHandle, )> { - let config = config + let mut config = config .into_core_config() .context("Failed to convert WorkerOptions to CoreWorkerConfig")?; + config.skip_client_worker_set_check = true; let runtime = runtime.borrow()?.core_runtime.clone(); enter_sync!(runtime); From 47058894b81a1226ed0c42ffc9591fadb02e82d9 Mon Sep 17 00:00:00 2001 From: Chris Olszewski Date: Mon, 27 Oct 2025 08:55:50 -0400 Subject: [PATCH 11/18] update core and remove bridge config altering --- packages/core-bridge/src/worker.rs | 3 +-- packages/test/src/test-integration-workflows.ts | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index 2a15a071e..d0d0cdff3 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -399,10 +399,9 @@ pub fn replay_worker_new( OpaqueOutboundHandle, OpaqueOutboundHandle, )> { - let mut config = config + let config = config .into_core_config() .context("Failed to convert WorkerOptions to CoreWorkerConfig")?; - config.skip_client_worker_set_check = true; let runtime = runtime.borrow()?.core_runtime.clone(); enter_sync!(runtime); diff --git a/packages/test/src/test-integration-workflows.ts b/packages/test/src/test-integration-workflows.ts index c75d3a33b..32620bee8 100644 --- a/packages/test/src/test-integration-workflows.ts +++ b/packages/test/src/test-integration-workflows.ts @@ -456,9 +456,7 @@ test('Worker requests Eager Activity Dispatch if possible', async (t) => { workflowBundle: undefined, }); const workflowWorkerConnection = await createNativeConnection(); - t.teardown(() => { - workflowWorkerConnection.close(); - }); + t.teardown(() => workflowWorkerConnection.close()); const workflowWorker = await createWorker({ connection: workflowWorkerConnection, activities: { From 42ff4f904aacfec89f4a3f42a17f0b9a920be849 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Tue, 28 Oct 2025 10:23:15 -0700 Subject: [PATCH 12/18] Worker heartbeating --- package.json | 3 +- packages/core-bridge/src/runtime.rs | 51 ++++++++++++++++++++++---- packages/core-bridge/ts/native.ts | 5 ++- packages/test/src/test-bridge.ts | 15 ++++++++ packages/worker/src/runtime-options.ts | 17 +++++++++ 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index c7a9c5ff7..a57b22501 100644 --- a/package.json +++ b/package.json @@ -102,5 +102,6 @@ "node": ">= 18.0.0", "npm": ">= 7.0.0", "rustc": ">= 1.53.0" - } + }, + "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808" } diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index 211e3bea1..e15a2a21d 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -36,6 +36,10 @@ macro_rules! enter_sync { pub fn init(cx: &mut neon::prelude::ModuleContext) -> neon::prelude::NeonResult<()> { cx.export_function("newRuntime", runtime_new)?; cx.export_function("runtimeShutdown", runtime_shutdown)?; + // cx.export_function( + // "runtimeGetWorkerHeartbeatIntervalMillis", + // runtime_get_worker_heartbeat_interval_millis, + // )?; Ok(()) } @@ -51,6 +55,7 @@ pub struct Runtime { // For some unknown reason, the otel metrics exporter will go crazy on shutdown in some // scenarios if we don't hold on to the `CoreOtelMeter` till the `Runtime` finally gets dropped. _otel_metrics_exporter: Option>, + // worker_heartbeat_interval_millis: Option, } /// Initialize Core global telemetry and create the tokio runtime required to run Core. @@ -59,11 +64,13 @@ pub struct Runtime { pub fn runtime_new( bridge_options: config::RuntimeOptions, ) -> BridgeResult> { - let (telemetry_options, metrics_options, logging_options) = bridge_options.try_into()?; + let (telemetry_options, metrics_options, logging_options, worker_heartbeat_interval_millis) = + bridge_options.try_into()?; // Create core runtime which starts tokio multi-thread runtime let runtime_options = RuntimeOptionsBuilder::default() .telemetry_options(telemetry_options) + .heartbeat_interval(worker_heartbeat_interval_millis.map(Duration::from_millis)) .build() .context("Failed to build runtime options")?; let mut core_runtime = CoreRuntime::new(runtime_options, TokioRuntimeBuilder::default()) @@ -125,6 +132,7 @@ pub fn runtime_new( log_exporter_task, metrics_exporter_task: prom_metrics_exporter_task.map(Arc::new), _otel_metrics_exporter: otel_metrics_exporter, + // worker_heartbeat_interval_millis: runtime_options.worker_heartbeat_interval.map(|d| d.as_millis() as u64), })) } @@ -138,6 +146,21 @@ pub fn runtime_shutdown(runtime: OpaqueInboundHandle) -> BridgeResult<( Ok(()) } +// #[js_function] +// pub fn runtime_get_worker_heartbeat_interval_millis( +// runtime: OpaqueInboundHandle, +// ) -> BridgeResult> { +// runtime +// .borrow()? +// .worker_heartbeat_interval_millis +// .map(u32::try_from) +// .transpose() +// .map_err(|_| BridgeError::TypeError { +// field: None, +// message: "workerHeartbeatIntervalMillis is too large to represent in JavaScript".into(), +// }) +// } + /// Drop will handle the cleanup impl MutableFinalize for Runtime {} @@ -265,6 +288,7 @@ mod config { log_exporter: LogExporterOptions, telemetry: TelemetryOptions, metrics_exporter: Option, + worker_heartbeat_interval_millis: Option, } #[derive(Debug, Clone, TryFromJs)] @@ -321,6 +345,7 @@ mod config { CoreTelemetryOptions, Option, super::BridgeLogExporter, + Option, )> for RuntimeOptions { type Error = BridgeError; @@ -330,8 +355,16 @@ mod config { CoreTelemetryOptions, Option, super::BridgeLogExporter, + Option, )> { - let (telemetry_logger, log_exporter) = match self.log_exporter { + let Self { + log_exporter, + telemetry, + metrics_exporter, + worker_heartbeat_interval_millis, + } = self; + + let (telemetry_logger, log_exporter) = match log_exporter { LogExporterOptions::Console { filter } => ( CoreTelemetryLogger::Console { filter }, BridgeLogExporter::Console, @@ -351,17 +384,21 @@ mod config { let mut telemetry_options = TelemetryOptionsBuilder::default(); let telemetry_options = telemetry_options .logging(telemetry_logger) - .metric_prefix(self.telemetry.metric_prefix) - .attach_service_name(self.telemetry.attach_service_name) + .metric_prefix(telemetry.metric_prefix) + .attach_service_name(telemetry.attach_service_name) .build() .context("Failed to build telemetry options")?; - let metrics_exporter = self - .metrics_exporter + let metrics_exporter = metrics_exporter .map(std::convert::TryInto::try_into) .transpose()?; - Ok((telemetry_options, metrics_exporter, log_exporter)) + Ok(( + telemetry_options, + metrics_exporter, + log_exporter, + worker_heartbeat_interval_millis, + )) } } diff --git a/packages/core-bridge/ts/native.ts b/packages/core-bridge/ts/native.ts index 2ddd20a1c..b5196e0dc 100644 --- a/packages/core-bridge/ts/native.ts +++ b/packages/core-bridge/ts/native.ts @@ -40,10 +40,12 @@ export type JsonString<_T> = string; // Runtime //////////////////////////////////////////////////////////////////////////////////////////////////// -export declare function newRuntime(telemOptions: RuntimeOptions): Runtime; +export declare function newRuntime(runtimeOptions: RuntimeOptions): Runtime; export declare function runtimeShutdown(runtime: Runtime): void; +export declare function runtimeGetWorkerHeartbeatIntervalMillis(runtime: Runtime): number | null; + export interface Runtime { type: 'runtime'; } @@ -52,6 +54,7 @@ export type RuntimeOptions = { logExporter: LogExporterOptions; telemetry: TelemetryOptions; metricsExporter: MetricExporterOptions; + workerHeartbeatIntervalMillis: Option; }; export type TelemetryOptions = { diff --git a/packages/test/src/test-bridge.ts b/packages/test/src/test-bridge.ts index df14e0183..e91b28c38 100644 --- a/packages/test/src/test-bridge.ts +++ b/packages/test/src/test-bridge.ts @@ -227,6 +227,20 @@ test("Stopping Worker after creating another runtime doesn't fail", async (t) => t.pass(); }); +test('Creating runtime with heartbeat enabled plumbs heartbeat duration', (t) => { + const runtime = native.newRuntime({ + ...GenericConfigs.runtime.basic, + workerHeartbeatIntervalMillis: 100, + }); + t.is(native.runtimeGetWorkerHeartbeatIntervalMillis(runtime), 100); + + const runtime1 = native.newRuntime({ + ...GenericConfigs.runtime.basic, + workerHeartbeatIntervalMillis: null, + }); + t.is(native.runtimeGetWorkerHeartbeatIntervalMillis(runtime1), null); +}); + // Sample configs /////////////////////////////////////////////////////////////////////////////////// const GenericConfigs = { @@ -241,6 +255,7 @@ const GenericConfigs = { attachServiceName: false, }, metricsExporter: null, + workerHeartbeatIntervalMillis: null, } satisfies native.RuntimeOptions, }, client: { diff --git a/packages/worker/src/runtime-options.ts b/packages/worker/src/runtime-options.ts index d38db5a87..e61150c07 100644 --- a/packages/worker/src/runtime-options.ts +++ b/packages/worker/src/runtime-options.ts @@ -32,6 +32,14 @@ export interface RuntimeOptions { */ telemetryOptions?: TelemetryOptions; + /** + * Interval for worker heartbeats. `null` disables heartbeating. + * + * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string} + * @default 60000 (60 seconds) + */ + workerHeartbeatInterval?: Duration | null; + /** * Automatically shutdown workers on any of these signals. * @@ -367,6 +375,14 @@ export function compileOptions(options: RuntimeOptions): CompiledRuntimeOptions const { metrics, noTemporalPrefixForMetrics } = options.telemetryOptions ?? {}; // eslint-disable-line deprecation/deprecation const [logger, logExporter] = compileLoggerOptions(options); + // Handle worker heartbeat interval - default to 60s, allow null to disable + let workerHeartbeatIntervalMillis: number | null; + if (options.workerHeartbeatInterval === null) { + workerHeartbeatIntervalMillis = null; + } else { + workerHeartbeatIntervalMillis = msToNumber(options.workerHeartbeatInterval ?? '60s'); + } + return { logger, shutdownSignals: options.shutdownSignals ?? ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGUSR2'], @@ -376,6 +392,7 @@ export function compileOptions(options: RuntimeOptions): CompiledRuntimeOptions metricPrefix: metrics?.metricPrefix ?? (noTemporalPrefixForMetrics ? '' : 'temporal_'), attachServiceName: metrics?.attachServiceName ?? true, }, + workerHeartbeatIntervalMillis, metricsExporter: metrics && isPrometheusMetricsExporter(metrics) ? ({ From 9d197d753e124de719a05e32aafea56872f35882 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Tue, 28 Oct 2025 11:59:00 -0700 Subject: [PATCH 13/18] Revert "Worker heartbeating" This reverts commit e09a2dcbd3d2b079a1278e1c0bfbff6e8026d005. --- package.json | 3 +- packages/core-bridge/src/runtime.rs | 51 ++++---------------------- packages/core-bridge/src/worker.rs | 2 +- packages/core-bridge/ts/native.ts | 5 +-- packages/test/src/test-bridge.ts | 15 -------- packages/worker/src/runtime-options.ts | 17 --------- 6 files changed, 10 insertions(+), 83 deletions(-) diff --git a/package.json b/package.json index a57b22501..c7a9c5ff7 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,5 @@ "node": ">= 18.0.0", "npm": ">= 7.0.0", "rustc": ">= 1.53.0" - }, - "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808" + } } diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index e15a2a21d..211e3bea1 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -36,10 +36,6 @@ macro_rules! enter_sync { pub fn init(cx: &mut neon::prelude::ModuleContext) -> neon::prelude::NeonResult<()> { cx.export_function("newRuntime", runtime_new)?; cx.export_function("runtimeShutdown", runtime_shutdown)?; - // cx.export_function( - // "runtimeGetWorkerHeartbeatIntervalMillis", - // runtime_get_worker_heartbeat_interval_millis, - // )?; Ok(()) } @@ -55,7 +51,6 @@ pub struct Runtime { // For some unknown reason, the otel metrics exporter will go crazy on shutdown in some // scenarios if we don't hold on to the `CoreOtelMeter` till the `Runtime` finally gets dropped. _otel_metrics_exporter: Option>, - // worker_heartbeat_interval_millis: Option, } /// Initialize Core global telemetry and create the tokio runtime required to run Core. @@ -64,13 +59,11 @@ pub struct Runtime { pub fn runtime_new( bridge_options: config::RuntimeOptions, ) -> BridgeResult> { - let (telemetry_options, metrics_options, logging_options, worker_heartbeat_interval_millis) = - bridge_options.try_into()?; + let (telemetry_options, metrics_options, logging_options) = bridge_options.try_into()?; // Create core runtime which starts tokio multi-thread runtime let runtime_options = RuntimeOptionsBuilder::default() .telemetry_options(telemetry_options) - .heartbeat_interval(worker_heartbeat_interval_millis.map(Duration::from_millis)) .build() .context("Failed to build runtime options")?; let mut core_runtime = CoreRuntime::new(runtime_options, TokioRuntimeBuilder::default()) @@ -132,7 +125,6 @@ pub fn runtime_new( log_exporter_task, metrics_exporter_task: prom_metrics_exporter_task.map(Arc::new), _otel_metrics_exporter: otel_metrics_exporter, - // worker_heartbeat_interval_millis: runtime_options.worker_heartbeat_interval.map(|d| d.as_millis() as u64), })) } @@ -146,21 +138,6 @@ pub fn runtime_shutdown(runtime: OpaqueInboundHandle) -> BridgeResult<( Ok(()) } -// #[js_function] -// pub fn runtime_get_worker_heartbeat_interval_millis( -// runtime: OpaqueInboundHandle, -// ) -> BridgeResult> { -// runtime -// .borrow()? -// .worker_heartbeat_interval_millis -// .map(u32::try_from) -// .transpose() -// .map_err(|_| BridgeError::TypeError { -// field: None, -// message: "workerHeartbeatIntervalMillis is too large to represent in JavaScript".into(), -// }) -// } - /// Drop will handle the cleanup impl MutableFinalize for Runtime {} @@ -288,7 +265,6 @@ mod config { log_exporter: LogExporterOptions, telemetry: TelemetryOptions, metrics_exporter: Option, - worker_heartbeat_interval_millis: Option, } #[derive(Debug, Clone, TryFromJs)] @@ -345,7 +321,6 @@ mod config { CoreTelemetryOptions, Option, super::BridgeLogExporter, - Option, )> for RuntimeOptions { type Error = BridgeError; @@ -355,16 +330,8 @@ mod config { CoreTelemetryOptions, Option, super::BridgeLogExporter, - Option, )> { - let Self { - log_exporter, - telemetry, - metrics_exporter, - worker_heartbeat_interval_millis, - } = self; - - let (telemetry_logger, log_exporter) = match log_exporter { + let (telemetry_logger, log_exporter) = match self.log_exporter { LogExporterOptions::Console { filter } => ( CoreTelemetryLogger::Console { filter }, BridgeLogExporter::Console, @@ -384,21 +351,17 @@ mod config { let mut telemetry_options = TelemetryOptionsBuilder::default(); let telemetry_options = telemetry_options .logging(telemetry_logger) - .metric_prefix(telemetry.metric_prefix) - .attach_service_name(telemetry.attach_service_name) + .metric_prefix(self.telemetry.metric_prefix) + .attach_service_name(self.telemetry.attach_service_name) .build() .context("Failed to build telemetry options")?; - let metrics_exporter = metrics_exporter + let metrics_exporter = self + .metrics_exporter .map(std::convert::TryInto::try_into) .transpose()?; - Ok(( - telemetry_options, - metrics_exporter, - log_exporter, - worker_heartbeat_interval_millis, - )) + Ok((telemetry_options, metrics_exporter, log_exporter)) } } diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index d0d0cdff3..d9a88d429 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -295,7 +295,7 @@ pub fn worker_complete_nexus_task( .complete_nexus_task(nexus_completion) .await .map_err(|err| match err { - CompleteNexusError::NexusNotEnabled => { + CompleteNexusError::NexusNotEnabled {} => { BridgeError::UnexpectedError(format!("{err}")) } CompleteNexusError::MalformedNexusCompletion { reason } => BridgeError::TypeError { diff --git a/packages/core-bridge/ts/native.ts b/packages/core-bridge/ts/native.ts index b5196e0dc..2ddd20a1c 100644 --- a/packages/core-bridge/ts/native.ts +++ b/packages/core-bridge/ts/native.ts @@ -40,12 +40,10 @@ export type JsonString<_T> = string; // Runtime //////////////////////////////////////////////////////////////////////////////////////////////////// -export declare function newRuntime(runtimeOptions: RuntimeOptions): Runtime; +export declare function newRuntime(telemOptions: RuntimeOptions): Runtime; export declare function runtimeShutdown(runtime: Runtime): void; -export declare function runtimeGetWorkerHeartbeatIntervalMillis(runtime: Runtime): number | null; - export interface Runtime { type: 'runtime'; } @@ -54,7 +52,6 @@ export type RuntimeOptions = { logExporter: LogExporterOptions; telemetry: TelemetryOptions; metricsExporter: MetricExporterOptions; - workerHeartbeatIntervalMillis: Option; }; export type TelemetryOptions = { diff --git a/packages/test/src/test-bridge.ts b/packages/test/src/test-bridge.ts index e91b28c38..df14e0183 100644 --- a/packages/test/src/test-bridge.ts +++ b/packages/test/src/test-bridge.ts @@ -227,20 +227,6 @@ test("Stopping Worker after creating another runtime doesn't fail", async (t) => t.pass(); }); -test('Creating runtime with heartbeat enabled plumbs heartbeat duration', (t) => { - const runtime = native.newRuntime({ - ...GenericConfigs.runtime.basic, - workerHeartbeatIntervalMillis: 100, - }); - t.is(native.runtimeGetWorkerHeartbeatIntervalMillis(runtime), 100); - - const runtime1 = native.newRuntime({ - ...GenericConfigs.runtime.basic, - workerHeartbeatIntervalMillis: null, - }); - t.is(native.runtimeGetWorkerHeartbeatIntervalMillis(runtime1), null); -}); - // Sample configs /////////////////////////////////////////////////////////////////////////////////// const GenericConfigs = { @@ -255,7 +241,6 @@ const GenericConfigs = { attachServiceName: false, }, metricsExporter: null, - workerHeartbeatIntervalMillis: null, } satisfies native.RuntimeOptions, }, client: { diff --git a/packages/worker/src/runtime-options.ts b/packages/worker/src/runtime-options.ts index e61150c07..d38db5a87 100644 --- a/packages/worker/src/runtime-options.ts +++ b/packages/worker/src/runtime-options.ts @@ -32,14 +32,6 @@ export interface RuntimeOptions { */ telemetryOptions?: TelemetryOptions; - /** - * Interval for worker heartbeats. `null` disables heartbeating. - * - * @format number of milliseconds or {@link https://www.npmjs.com/package/ms | ms-formatted string} - * @default 60000 (60 seconds) - */ - workerHeartbeatInterval?: Duration | null; - /** * Automatically shutdown workers on any of these signals. * @@ -375,14 +367,6 @@ export function compileOptions(options: RuntimeOptions): CompiledRuntimeOptions const { metrics, noTemporalPrefixForMetrics } = options.telemetryOptions ?? {}; // eslint-disable-line deprecation/deprecation const [logger, logExporter] = compileLoggerOptions(options); - // Handle worker heartbeat interval - default to 60s, allow null to disable - let workerHeartbeatIntervalMillis: number | null; - if (options.workerHeartbeatInterval === null) { - workerHeartbeatIntervalMillis = null; - } else { - workerHeartbeatIntervalMillis = msToNumber(options.workerHeartbeatInterval ?? '60s'); - } - return { logger, shutdownSignals: options.shutdownSignals ?? ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGUSR2'], @@ -392,7 +376,6 @@ export function compileOptions(options: RuntimeOptions): CompiledRuntimeOptions metricPrefix: metrics?.metricPrefix ?? (noTemporalPrefixForMetrics ? '' : 'temporal_'), attachServiceName: metrics?.attachServiceName ?? true, }, - workerHeartbeatIntervalMillis, metricsExporter: metrics && isPrometheusMetricsExporter(metrics) ? ({ From 36b0fb6b390ca652399c6360ab9aa367b30eaff7 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Mon, 10 Nov 2025 12:38:28 -0800 Subject: [PATCH 14/18] update core to 0e81599 --- packages/core-bridge/sdk-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index da2028d86..0e8159908 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit da2028d86fc35eb28037045342a68f134824f186 +Subproject commit 0e815990874b7a3d14b01cd9fc0bad22a9be0aac From aa705f55a1e966027702403458e2faeb550be0ff Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Mon, 10 Nov 2025 12:59:02 -0800 Subject: [PATCH 15/18] format --- packages/core-bridge/src/worker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-bridge/src/worker.rs b/packages/core-bridge/src/worker.rs index d9a88d429..d0d0cdff3 100644 --- a/packages/core-bridge/src/worker.rs +++ b/packages/core-bridge/src/worker.rs @@ -295,7 +295,7 @@ pub fn worker_complete_nexus_task( .complete_nexus_task(nexus_completion) .await .map_err(|err| match err { - CompleteNexusError::NexusNotEnabled {} => { + CompleteNexusError::NexusNotEnabled => { BridgeError::UnexpectedError(format!("{err}")) } CompleteNexusError::MalformedNexusCompletion { reason } => BridgeError::TypeError { From b81665e1fd51f964b4b9b8f3055bbe30bfbef8e9 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Mon, 10 Nov 2025 13:10:12 -0800 Subject: [PATCH 16/18] fix plugin tests to use different task queue --- packages/test/src/test-plugins.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/test/src/test-plugins.ts b/packages/test/src/test-plugins.ts index 1bf33e852..a41c6687b 100644 --- a/packages/test/src/test-plugins.ts +++ b/packages/test/src/test-plugins.ts @@ -46,7 +46,7 @@ export class ExamplePlugin configureWorker(config: WorkerOptions): WorkerOptions { console.log('ExamplePlugin: Configuring worker'); - config.taskQueue = 'plugin-task-queue'; + config.taskQueue = 'plugin-task-queue' + randomUUID(); return config; } @@ -75,9 +75,9 @@ test('Basic plugin', async (t) => { }); await worker.runUntil(async () => { - t.is(worker.options.taskQueue, 'plugin-task-queue'); + t.true(worker.options.taskQueue.startsWith('plugin-task-queue')); const result = await client.workflow.execute(helloWorkflow, { - taskQueue: 'plugin-task-queue', + taskQueue: worker.options.taskQueue, workflowExecutionTimeout: '30 seconds', workflowId: randomUUID(), }); @@ -97,9 +97,9 @@ test('Bundler plugins are passed from worker', async (t) => { plugins: [new ExamplePlugin()], }); await worker.runUntil(async () => { - t.is(worker.options.taskQueue, 'plugin-task-queue'); + t.true(worker.options.taskQueue.startsWith('plugin-task-queue')); const result = await client.workflow.execute(helloWorkflow, { - taskQueue: 'plugin-task-queue', + taskQueue: worker.options.taskQueue, workflowExecutionTimeout: '30 seconds', workflowId: randomUUID(), }); @@ -119,12 +119,12 @@ test('Worker plugins are passed from native connection', async (t) => { taskQueue: 'will be overridden', }); - t.is(worker.options.taskQueue, 'plugin-task-queue'); + t.true(worker.options.taskQueue.startsWith('plugin-task-queue')); await worker.runUntil(async () => { - t.is(worker.options.taskQueue, 'plugin-task-queue'); + t.true(worker.options.taskQueue.startsWith('plugin-task-queue')); const result = await client.workflow.execute(helloWorkflow, { - taskQueue: 'plugin-task-queue', + taskQueue: worker.options.taskQueue, workflowExecutionTimeout: '30 seconds', workflowId: randomUUID(), }); @@ -162,13 +162,13 @@ test('Bundler plugins are passed from connections', async (t) => { const worker = await Worker.create({ workflowsPath: 'replaced', connection: env.nativeConnection, - taskQueue: 'plugin-task-queue', + taskQueue: 'plugin-task-queue' + randomUUID(), }); await worker.runUntil(async () => { - t.is(worker.options.taskQueue, 'plugin-task-queue'); + t.true(worker.options.taskQueue.startsWith('plugin-task-queue')); const result = await client.workflow.execute(helloWorkflow, { - taskQueue: 'plugin-task-queue', + taskQueue: worker.options.taskQueue, workflowExecutionTimeout: '30 seconds', workflowId: randomUUID(), }); @@ -206,13 +206,13 @@ test('SimplePlugin worker configurations', async (t) => { const worker = await Worker.create({ workflowsPath: 'replaced', connection: t.context.testEnv.nativeConnection, - taskQueue: 'simple-plugin-queue', + taskQueue: 'simple-plugin-queue' + randomUUID(), plugins: [plugin], }); await worker.runUntil(async () => { const result = await client.workflow.execute(activityWorkflow, { - taskQueue: 'simple-plugin-queue', + taskQueue: worker.options.taskQueue, workflowExecutionTimeout: '30 seconds', workflowId: randomUUID(), }); @@ -234,7 +234,7 @@ test('SimplePlugin with activities merges them correctly', async (t) => { const worker = await Worker.create({ connection: t.context.testEnv.nativeConnection, - taskQueue: 'simple-plugin-queue', + taskQueue: 'simple-plugin-queue' + randomUUID(), activities: { existingActivity: activity1, }, From 0bd23639e8ddb9812cb43cdf21ba032d97fba942 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Mon, 10 Nov 2025 13:33:25 -0800 Subject: [PATCH 17/18] Disable worker heartbeating by default --- packages/core-bridge/src/runtime.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index 211e3bea1..24993b1bd 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -64,6 +64,7 @@ pub fn runtime_new( // Create core runtime which starts tokio multi-thread runtime let runtime_options = RuntimeOptionsBuilder::default() .telemetry_options(telemetry_options) + .heartbeat_interval(None) .build() .context("Failed to build runtime options")?; let mut core_runtime = CoreRuntime::new(runtime_options, TokioRuntimeBuilder::default()) From 4dbd8894a01474edb8fbcfa8aa85706156930928 Mon Sep 17 00:00:00 2001 From: Andrew Yuan Date: Mon, 10 Nov 2025 14:42:54 -0800 Subject: [PATCH 18/18] bump core ver --- packages/core-bridge/sdk-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index 0e8159908..850db67c8 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit 0e815990874b7a3d14b01cd9fc0bad22a9be0aac +Subproject commit 850db67c87ac9208da53df1cd82f8a36d71c5227