@temporalio/core-bridge 1.13.0 → 1.13.2

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.
Files changed (181) hide show
  1. package/Cargo.lock +239 -382
  2. package/Cargo.toml +11 -11
  3. package/lib/native.d.ts +10 -3
  4. package/package.json +3 -3
  5. package/releases/aarch64-apple-darwin/index.node +0 -0
  6. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  7. package/releases/x86_64-apple-darwin/index.node +0 -0
  8. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  9. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  10. package/sdk-core/.cargo/config.toml +71 -11
  11. package/sdk-core/.clippy.toml +1 -0
  12. package/sdk-core/.github/workflows/heavy.yml +2 -0
  13. package/sdk-core/.github/workflows/per-pr.yml +50 -18
  14. package/sdk-core/ARCHITECTURE.md +44 -48
  15. package/sdk-core/Cargo.toml +26 -7
  16. package/sdk-core/README.md +4 -0
  17. package/sdk-core/arch_docs/diagrams/TimerMachine_Coverage.puml +14 -0
  18. package/sdk-core/arch_docs/diagrams/initial_event_history.png +0 -0
  19. package/sdk-core/arch_docs/sdks_intro.md +299 -0
  20. package/sdk-core/client/Cargo.toml +8 -7
  21. package/sdk-core/client/src/callback_based.rs +1 -2
  22. package/sdk-core/client/src/lib.rs +485 -299
  23. package/sdk-core/client/src/metrics.rs +32 -8
  24. package/sdk-core/client/src/proxy.rs +124 -5
  25. package/sdk-core/client/src/raw.rs +598 -307
  26. package/sdk-core/client/src/replaceable.rs +253 -0
  27. package/sdk-core/client/src/retry.rs +9 -6
  28. package/sdk-core/client/src/worker_registry/mod.rs +19 -3
  29. package/sdk-core/client/src/workflow_handle/mod.rs +20 -17
  30. package/sdk-core/core/Cargo.toml +100 -31
  31. package/sdk-core/core/src/core_tests/activity_tasks.rs +55 -225
  32. package/sdk-core/core/src/core_tests/mod.rs +2 -8
  33. package/sdk-core/core/src/core_tests/queries.rs +3 -5
  34. package/sdk-core/core/src/core_tests/replay_flag.rs +3 -62
  35. package/sdk-core/core/src/core_tests/updates.rs +4 -5
  36. package/sdk-core/core/src/core_tests/workers.rs +4 -3
  37. package/sdk-core/core/src/core_tests/workflow_cancels.rs +10 -7
  38. package/sdk-core/core/src/core_tests/workflow_tasks.rs +28 -291
  39. package/sdk-core/core/src/ephemeral_server/mod.rs +15 -3
  40. package/sdk-core/core/src/internal_flags.rs +11 -1
  41. package/sdk-core/core/src/lib.rs +50 -36
  42. package/sdk-core/core/src/pollers/mod.rs +5 -5
  43. package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
  44. package/sdk-core/core/src/protosext/mod.rs +13 -5
  45. package/sdk-core/core/src/protosext/protocol_messages.rs +4 -11
  46. package/sdk-core/core/src/retry_logic.rs +256 -108
  47. package/sdk-core/core/src/telemetry/metrics.rs +1 -0
  48. package/sdk-core/core/src/telemetry/mod.rs +8 -2
  49. package/sdk-core/core/src/telemetry/prometheus_meter.rs +2 -2
  50. package/sdk-core/core/src/test_help/integ_helpers.rs +971 -0
  51. package/sdk-core/core/src/test_help/mod.rs +10 -1100
  52. package/sdk-core/core/src/test_help/unit_helpers.rs +218 -0
  53. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +42 -6
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +19 -19
  55. package/sdk-core/core/src/worker/activities.rs +10 -3
  56. package/sdk-core/core/src/worker/client/mocks.rs +3 -3
  57. package/sdk-core/core/src/worker/client.rs +130 -93
  58. package/sdk-core/core/src/worker/heartbeat.rs +12 -13
  59. package/sdk-core/core/src/worker/mod.rs +31 -21
  60. package/sdk-core/core/src/worker/nexus.rs +14 -3
  61. package/sdk-core/core/src/worker/slot_provider.rs +9 -0
  62. package/sdk-core/core/src/worker/tuner.rs +159 -0
  63. package/sdk-core/core/src/worker/workflow/history_update.rs +3 -265
  64. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -54
  65. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -82
  66. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -67
  67. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -192
  68. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -43
  69. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +6 -554
  70. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -71
  71. package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +102 -3
  72. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +10 -539
  73. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -139
  74. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -119
  75. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -63
  76. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +9 -4
  77. package/sdk-core/core/src/worker/workflow/mod.rs +5 -1
  78. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +8 -3
  79. package/sdk-core/core-api/Cargo.toml +4 -4
  80. package/sdk-core/core-api/src/envconfig.rs +153 -54
  81. package/sdk-core/core-api/src/lib.rs +68 -0
  82. package/sdk-core/core-api/src/telemetry/metrics.rs +2 -1
  83. package/sdk-core/core-api/src/telemetry.rs +13 -0
  84. package/sdk-core/core-c-bridge/Cargo.toml +13 -8
  85. package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +184 -22
  86. package/sdk-core/core-c-bridge/src/client.rs +462 -184
  87. package/sdk-core/core-c-bridge/src/envconfig.rs +314 -0
  88. package/sdk-core/core-c-bridge/src/lib.rs +1 -0
  89. package/sdk-core/core-c-bridge/src/random.rs +4 -4
  90. package/sdk-core/core-c-bridge/src/runtime.rs +22 -23
  91. package/sdk-core/core-c-bridge/src/testing.rs +1 -4
  92. package/sdk-core/core-c-bridge/src/tests/context.rs +31 -31
  93. package/sdk-core/core-c-bridge/src/tests/mod.rs +32 -28
  94. package/sdk-core/core-c-bridge/src/tests/utils.rs +7 -7
  95. package/sdk-core/core-c-bridge/src/worker.rs +319 -66
  96. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -1
  97. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +5 -5
  98. package/sdk-core/sdk/Cargo.toml +8 -2
  99. package/sdk-core/sdk/src/activity_context.rs +1 -1
  100. package/sdk-core/sdk/src/app_data.rs +1 -1
  101. package/sdk-core/sdk/src/interceptors.rs +1 -4
  102. package/sdk-core/sdk/src/lib.rs +1 -5
  103. package/sdk-core/sdk/src/workflow_context/options.rs +10 -1
  104. package/sdk-core/sdk/src/workflow_future.rs +1 -1
  105. package/sdk-core/sdk-core-protos/Cargo.toml +6 -6
  106. package/sdk-core/sdk-core-protos/build.rs +10 -23
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/create-release.yml +9 -1
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +254 -5
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +234 -5
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +1 -1
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +6 -0
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -2
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -2
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -6
  115. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  116. package/sdk-core/{test-utils → sdk-core-protos}/src/canned_histories.rs +5 -5
  117. package/sdk-core/sdk-core-protos/src/history_builder.rs +2 -2
  118. package/sdk-core/sdk-core-protos/src/lib.rs +25 -9
  119. package/sdk-core/sdk-core-protos/src/test_utils.rs +89 -0
  120. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -5
  121. package/sdk-core/tests/c_bridge_smoke_test.c +10 -0
  122. package/sdk-core/tests/cloud_tests.rs +10 -8
  123. package/sdk-core/tests/common/http_proxy.rs +134 -0
  124. package/sdk-core/{test-utils/src/lib.rs → tests/common/mod.rs} +214 -281
  125. package/sdk-core/{test-utils/src → tests/common}/workflows.rs +4 -3
  126. package/sdk-core/tests/fuzzy_workflow.rs +1 -1
  127. package/sdk-core/tests/global_metric_tests.rs +8 -7
  128. package/sdk-core/tests/heavy_tests.rs +7 -3
  129. package/sdk-core/tests/integ_tests/client_tests.rs +111 -24
  130. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +14 -9
  131. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +4 -4
  132. package/sdk-core/tests/integ_tests/metrics_tests.rs +114 -14
  133. package/sdk-core/tests/integ_tests/pagination_tests.rs +273 -0
  134. package/sdk-core/tests/integ_tests/polling_tests.rs +311 -93
  135. package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
  136. package/sdk-core/tests/integ_tests/update_tests.rs +13 -7
  137. package/sdk-core/tests/integ_tests/visibility_tests.rs +26 -9
  138. package/sdk-core/tests/integ_tests/worker_tests.rs +668 -13
  139. package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +40 -24
  140. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +244 -11
  141. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
  142. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +78 -2
  143. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +61 -2
  144. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +465 -7
  145. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +41 -2
  146. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +315 -3
  147. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +1 -1
  148. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1990 -14
  149. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +65 -2
  150. package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +123 -23
  151. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +525 -3
  152. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +65 -16
  153. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +32 -23
  154. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +126 -5
  155. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +1 -2
  156. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +124 -8
  157. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +62 -2
  158. package/sdk-core/tests/integ_tests/workflow_tests.rs +67 -8
  159. package/sdk-core/tests/main.rs +26 -17
  160. package/sdk-core/tests/manual_tests.rs +5 -1
  161. package/sdk-core/tests/runner.rs +22 -40
  162. package/sdk-core/tests/shared_tests/mod.rs +1 -1
  163. package/sdk-core/tests/shared_tests/priority.rs +1 -1
  164. package/sdk-core/{core/benches/workflow_replay.rs → tests/workflow_replay_bench.rs} +10 -5
  165. package/src/client.rs +97 -20
  166. package/src/helpers/callbacks.rs +4 -4
  167. package/src/helpers/errors.rs +7 -1
  168. package/src/helpers/handles.rs +1 -0
  169. package/src/helpers/try_from_js.rs +4 -3
  170. package/src/lib.rs +3 -2
  171. package/src/metrics.rs +3 -0
  172. package/src/runtime.rs +5 -2
  173. package/src/worker.rs +9 -12
  174. package/ts/native.ts +13 -3
  175. package/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  176. package/sdk-core/core/src/core_tests/child_workflows.rs +0 -281
  177. package/sdk-core/core/src/core_tests/determinism.rs +0 -318
  178. package/sdk-core/core/src/core_tests/local_activities.rs +0 -1442
  179. package/sdk-core/test-utils/Cargo.toml +0 -38
  180. package/sdk-core/test-utils/src/histfetch.rs +0 -28
  181. package/sdk-core/test-utils/src/interceptors.rs +0 -46
@@ -138,9 +138,9 @@ pub struct ClientConfigProfile {
138
138
  /// ClientConfigTLS is TLS configuration for a client.
139
139
  #[derive(Debug, Clone, PartialEq, Default)]
140
140
  pub struct ClientConfigTLS {
141
- /// If true, TLS is explicitly disabled. If false/unset, whether TLS is enabled or not depends on other factors such
142
- /// as whether this struct is present or None, and whether API key exists (which enables TLS by default).
143
- pub disabled: bool,
141
+ /// If Some(true), TLS is explicitly disabled. If Some(false), TLS is explicitly enabled.
142
+ /// If None, TLS behavior depends on other factors (API key presence, etc.)
143
+ pub disabled: Option<bool>,
144
144
 
145
145
  /// Client certificate source.
146
146
  pub client_cert: Option<DataSource>,
@@ -358,9 +358,6 @@ pub fn load_client_config_profile(
358
358
  profile.load_from_env(env_vars)?;
359
359
  }
360
360
 
361
- // Apply API key → TLS auto-enabling logic
362
- profile.apply_api_key_tls_logic();
363
-
364
361
  Ok(profile)
365
362
  }
366
363
 
@@ -446,7 +443,7 @@ impl ClientConfigProfile {
446
443
  if let Some(disabled_str) = env_provider.get("TEMPORAL_TLS")?
447
444
  && let Some(disabled) = env_var_to_bool(&disabled_str)
448
445
  {
449
- tls.disabled = !disabled;
446
+ tls.disabled = Some(!disabled);
450
447
  }
451
448
 
452
449
  apply_data_source_env_var(
@@ -528,14 +525,6 @@ impl ClientConfigProfile {
528
525
  }
529
526
  Ok(())
530
527
  }
531
-
532
- /// Apply automatic TLS enabling when API key is present
533
- pub fn apply_api_key_tls_logic(&mut self) {
534
- if self.api_key.is_some() && self.tls.is_none() {
535
- // If API key is present but no TLS config exists, create one with TLS enabled
536
- self.tls = Some(ClientConfigTLS::default());
537
- }
538
- }
539
528
  }
540
529
 
541
530
  /// Helper to check if any of the given environment variables are set.
@@ -729,8 +718,8 @@ impl TomlClientConfigProfile {
729
718
 
730
719
  #[derive(Debug, Clone, Serialize, Deserialize)]
731
720
  struct TomlClientConfigTLS {
732
- #[serde(default, skip_serializing_if = "std::ops::Not::not")]
733
- disabled: bool,
721
+ #[serde(default, skip_serializing_if = "Option::is_none")]
722
+ disabled: Option<bool>,
734
723
 
735
724
  #[serde(skip_serializing_if = "Option::is_none")]
736
725
  client_cert_path: Option<String>,
@@ -760,7 +749,7 @@ struct TomlClientConfigTLS {
760
749
  impl TomlClientConfigTLS {
761
750
  fn new() -> Self {
762
751
  Self {
763
- disabled: false,
752
+ disabled: None,
764
753
  client_cert_path: None,
765
754
  client_cert_data: None,
766
755
  client_key_path: None,
@@ -951,7 +940,7 @@ mod strict {
951
940
  #[serde(deny_unknown_fields)]
952
941
  struct StrictTomlClientConfigTLS {
953
942
  #[serde(default)]
954
- disabled: bool,
943
+ disabled: Option<bool>,
955
944
  #[serde(default)]
956
945
  client_cert_path: Option<String>,
957
946
  #[serde(default)]
@@ -1068,7 +1057,7 @@ namespace = "production"
1068
1057
  assert_eq!(default_profile.api_key.as_ref().unwrap(), "test-key");
1069
1058
 
1070
1059
  let tls = default_profile.tls.as_ref().unwrap();
1071
- assert!(!tls.disabled);
1060
+ assert_eq!(tls.disabled, Some(false)); // Explicitly set to false
1072
1061
  assert_eq!(
1073
1062
  tls.client_cert,
1074
1063
  Some(DataSource::Path("/path/to/cert".to_string()))
@@ -1244,7 +1233,7 @@ some-other-header = "some-value2"
1244
1233
  assert_eq!(profile.api_key.as_ref().unwrap(), "my-api-key-new");
1245
1234
 
1246
1235
  let tls = profile.tls.as_ref().unwrap();
1247
- assert!(!tls.disabled); // TLS enabled via env var
1236
+ assert_eq!(tls.disabled, Some(false)); // TLS enabled via env var
1248
1237
  assert_eq!(
1249
1238
  tls.client_cert,
1250
1239
  Some(DataSource::Path("my-client-cert-path-new".to_string()))
@@ -1313,7 +1302,7 @@ sOme-hEader_key = "some-value"
1313
1302
  assert_eq!(codec.auth.as_ref().unwrap(), "my-auth");
1314
1303
 
1315
1304
  let tls = profile.tls.as_ref().unwrap();
1316
- assert!(tls.disabled);
1305
+ assert_eq!(tls.disabled, Some(true)); // Explicitly disabled
1317
1306
  assert_eq!(
1318
1307
  tls.client_cert,
1319
1308
  Some(DataSource::Path("my-client-cert-path".to_string()))
@@ -1361,7 +1350,7 @@ api_key = "my-api-key"
1361
1350
  assert!(profile.tls.is_some());
1362
1351
 
1363
1352
  let tls = profile.tls.as_ref().unwrap();
1364
- assert!(!tls.disabled); // default value
1353
+ assert_eq!(tls.disabled, None); // Not explicitly set // default value
1365
1354
  assert!(tls.client_cert.is_none());
1366
1355
  }
1367
1356
 
@@ -1582,27 +1571,6 @@ address = "localhost:7233"
1582
1571
  assert_eq!(profile.namespace.as_ref().unwrap(), "env-namespace");
1583
1572
  }
1584
1573
 
1585
- #[test]
1586
- fn test_api_key_tls_auto_enable() {
1587
- // Test 1: When API key is present, TLS should be automatically enabled
1588
- let toml_str = r#"
1589
- [profile.default]
1590
- api_key = "my-api-key"
1591
- "#;
1592
-
1593
- let options = LoadClientConfigProfileOptions {
1594
- config_source: Some(DataSource::Data(toml_str.as_bytes().to_vec())),
1595
- ..Default::default()
1596
- };
1597
-
1598
- let profile = load_client_config_profile(options, None).unwrap();
1599
-
1600
- // TLS should be enabled due to API key presence
1601
- assert!(profile.tls.is_some());
1602
- let tls = profile.tls.as_ref().unwrap();
1603
- assert!(!tls.disabled);
1604
- }
1605
-
1606
1574
  #[test]
1607
1575
  fn test_no_api_key_no_tls_is_none() {
1608
1576
  // Test that if no API key is present and no TLS block exists, TLS config is None
@@ -1624,12 +1592,38 @@ address = "some-address"
1624
1592
 
1625
1593
  #[test]
1626
1594
  fn test_load_client_config_profile_from_system_env() {
1627
- // Set up system env vars. These tests can't be run in parallel.
1628
- unsafe {
1629
- std::env::set_var("TEMPORAL_ADDRESS", "system-address");
1630
- std::env::set_var("TEMPORAL_NAMESPACE", "system-namespace");
1631
- }
1595
+ let cargo = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
1596
+ let output = std::process::Command::new(cargo)
1597
+ .arg("test")
1598
+ .arg("-F")
1599
+ .arg("envconfig")
1600
+ .arg("envconfig::tests::test_load_client_config_profile_from_system_env_impl")
1601
+ .arg("--")
1602
+ .arg("--exact")
1603
+ .arg("--ignored")
1604
+ .env("TEMPORAL_ADDRESS", "system-address")
1605
+ .env("TEMPORAL_NAMESPACE", "system-namespace")
1606
+ .output()
1607
+ .expect("Failed to execute subprocess test");
1632
1608
 
1609
+ assert!(
1610
+ output.status.success(),
1611
+ "Subprocess test failed:\nstdout: {}\nstderr: {}",
1612
+ String::from_utf8_lossy(&output.stdout),
1613
+ String::from_utf8_lossy(&output.stderr),
1614
+ );
1615
+ }
1616
+
1617
+ #[test]
1618
+ #[ignore] // Only run when explicitly called
1619
+ fn test_load_client_config_profile_from_system_env_impl() {
1620
+ // Check if we're in the right context
1621
+ if std::env::var("TEMPORAL_ADDRESS").is_err()
1622
+ || std::env::var("TEMPORAL_NAMESPACE").is_err()
1623
+ {
1624
+ eprintln!("Skipping test - required env vars not set");
1625
+ return; // Early return instead of panic
1626
+ }
1633
1627
  let options = LoadClientConfigProfileOptions {
1634
1628
  disable_file: true, // Don't load from any files
1635
1629
  ..Default::default()
@@ -1639,11 +1633,116 @@ address = "some-address"
1639
1633
  let profile = load_client_config_profile(options, None).unwrap();
1640
1634
  assert_eq!(profile.address.as_ref().unwrap(), "system-address");
1641
1635
  assert_eq!(profile.namespace.as_ref().unwrap(), "system-namespace");
1636
+ }
1642
1637
 
1643
- // Clean up
1644
- unsafe {
1645
- std::env::remove_var("TEMPORAL_ADDRESS");
1646
- std::env::remove_var("TEMPORAL_NAMESPACE");
1647
- }
1638
+ #[test]
1639
+ fn test_tls_disabled_tri_state_behavior() {
1640
+ // Test 1: disabled = None (unset) - should not appear in TOML
1641
+ let tls_unset = ClientConfigTLS {
1642
+ disabled: None,
1643
+ ..Default::default()
1644
+ };
1645
+ let profile_unset = ClientConfigProfile {
1646
+ address: Some("localhost:7233".to_string()),
1647
+ tls: Some(tls_unset),
1648
+ ..Default::default()
1649
+ };
1650
+ let mut config_unset = ClientConfig::default();
1651
+ config_unset
1652
+ .profiles
1653
+ .insert("test".to_string(), profile_unset);
1654
+
1655
+ let toml_unset = config_unset.to_toml().unwrap();
1656
+ let toml_str_unset = String::from_utf8(toml_unset).unwrap();
1657
+
1658
+ // Unset disabled should not appear in TOML output
1659
+ assert!(!toml_str_unset.contains("disabled"));
1660
+
1661
+ // Round-trip test - should remain None
1662
+ let parsed_unset =
1663
+ ClientConfig::from_toml(toml_str_unset.as_bytes(), Default::default()).unwrap();
1664
+ assert_eq!(
1665
+ parsed_unset
1666
+ .profiles
1667
+ .get("test")
1668
+ .unwrap()
1669
+ .tls
1670
+ .as_ref()
1671
+ .unwrap()
1672
+ .disabled,
1673
+ None
1674
+ );
1675
+
1676
+ // Test 2: disabled = Some(false) (explicitly enabled) - should appear in TOML as false
1677
+ let tls_enabled = ClientConfigTLS {
1678
+ disabled: Some(false),
1679
+ ..Default::default()
1680
+ };
1681
+ let profile_enabled = ClientConfigProfile {
1682
+ address: Some("localhost:7233".to_string()),
1683
+ tls: Some(tls_enabled),
1684
+ ..Default::default()
1685
+ };
1686
+ let mut config_enabled = ClientConfig::default();
1687
+ config_enabled
1688
+ .profiles
1689
+ .insert("test".to_string(), profile_enabled);
1690
+
1691
+ let toml_enabled = config_enabled.to_toml().unwrap();
1692
+ let toml_str_enabled = String::from_utf8(toml_enabled).unwrap();
1693
+
1694
+ // Explicitly disabled=false should appear in TOML
1695
+ assert!(toml_str_enabled.contains("disabled = false"));
1696
+
1697
+ // Round-trip test - should remain Some(false)
1698
+ let parsed_enabled =
1699
+ ClientConfig::from_toml(toml_str_enabled.as_bytes(), Default::default()).unwrap();
1700
+ assert_eq!(
1701
+ parsed_enabled
1702
+ .profiles
1703
+ .get("test")
1704
+ .unwrap()
1705
+ .tls
1706
+ .as_ref()
1707
+ .unwrap()
1708
+ .disabled,
1709
+ Some(false)
1710
+ );
1711
+
1712
+ // Test 3: disabled = Some(true) (explicitly disabled) - should appear in TOML as true
1713
+ let tls_disabled = ClientConfigTLS {
1714
+ disabled: Some(true),
1715
+ ..Default::default()
1716
+ };
1717
+ let profile_disabled = ClientConfigProfile {
1718
+ address: Some("localhost:7233".to_string()),
1719
+ tls: Some(tls_disabled),
1720
+ ..Default::default()
1721
+ };
1722
+ let mut config_disabled = ClientConfig::default();
1723
+ config_disabled
1724
+ .profiles
1725
+ .insert("test".to_string(), profile_disabled);
1726
+
1727
+ let toml_disabled = config_disabled.to_toml().unwrap();
1728
+ let toml_str_disabled = String::from_utf8(toml_disabled).unwrap();
1729
+
1730
+ // Explicitly disabled=true should appear in TOML
1731
+ assert!(toml_str_disabled.contains("disabled = true"));
1732
+
1733
+ // Round-trip test - should remain Some(true)
1734
+ let parsed_disabled =
1735
+ ClientConfig::from_toml(toml_str_disabled.as_bytes(), Default::default()).unwrap();
1736
+ assert_eq!(
1737
+ parsed_disabled
1738
+ .profiles
1739
+ .get("test")
1740
+ .unwrap()
1741
+ .tls
1742
+ .as_ref()
1743
+ .unwrap()
1744
+ .disabled,
1745
+ Some(true)
1746
+ );
1648
1747
  }
1649
1748
  }
@@ -11,6 +11,7 @@ use crate::{
11
11
  },
12
12
  worker::WorkerConfig,
13
13
  };
14
+ use std::sync::Arc;
14
15
  use temporal_sdk_core_protos::coresdk::{
15
16
  ActivityHeartbeat, ActivityTaskCompletion,
16
17
  activity_task::ActivityTask,
@@ -139,6 +140,73 @@ pub trait Worker: Send + Sync {
139
140
  async fn finalize_shutdown(self);
140
141
  }
141
142
 
143
+ #[async_trait::async_trait]
144
+ impl<W> Worker for Arc<W>
145
+ where
146
+ W: Worker + ?Sized,
147
+ {
148
+ async fn validate(&self) -> Result<(), WorkerValidationError> {
149
+ (**self).validate().await
150
+ }
151
+
152
+ async fn poll_workflow_activation(&self) -> Result<WorkflowActivation, PollError> {
153
+ (**self).poll_workflow_activation().await
154
+ }
155
+
156
+ async fn poll_activity_task(&self) -> Result<ActivityTask, PollError> {
157
+ (**self).poll_activity_task().await
158
+ }
159
+
160
+ async fn poll_nexus_task(&self) -> Result<NexusTask, PollError> {
161
+ (**self).poll_nexus_task().await
162
+ }
163
+
164
+ async fn complete_workflow_activation(
165
+ &self,
166
+ completion: WorkflowActivationCompletion,
167
+ ) -> Result<(), CompleteWfError> {
168
+ (**self).complete_workflow_activation(completion).await
169
+ }
170
+
171
+ async fn complete_activity_task(
172
+ &self,
173
+ completion: ActivityTaskCompletion,
174
+ ) -> Result<(), CompleteActivityError> {
175
+ (**self).complete_activity_task(completion).await
176
+ }
177
+
178
+ async fn complete_nexus_task(
179
+ &self,
180
+ completion: NexusTaskCompletion,
181
+ ) -> Result<(), CompleteNexusError> {
182
+ (**self).complete_nexus_task(completion).await
183
+ }
184
+
185
+ fn record_activity_heartbeat(&self, details: ActivityHeartbeat) {
186
+ (**self).record_activity_heartbeat(details)
187
+ }
188
+
189
+ fn request_workflow_eviction(&self, run_id: &str) {
190
+ (**self).request_workflow_eviction(run_id)
191
+ }
192
+
193
+ fn get_config(&self) -> &WorkerConfig {
194
+ (**self).get_config()
195
+ }
196
+
197
+ fn initiate_shutdown(&self) {
198
+ (**self).initiate_shutdown()
199
+ }
200
+
201
+ async fn shutdown(&self) {
202
+ (**self).shutdown().await
203
+ }
204
+
205
+ async fn finalize_shutdown(self) {
206
+ panic!("Can't finalize shutdown on Arc'd worker")
207
+ }
208
+ }
209
+
142
210
  macro_rules! dbg_panic {
143
211
  ($($arg:tt)*) => {
144
212
  use tracing::error;
@@ -1,4 +1,4 @@
1
- use crate::dbg_panic;
1
+ use crate::{dbg_panic, telemetry::TaskQueueLabelStrategy};
2
2
  use std::{
3
3
  any::Any,
4
4
  borrow::Cow,
@@ -64,6 +64,7 @@ impl From<&'static str> for MetricParameters {
64
64
  pub struct TemporalMeter {
65
65
  pub inner: Arc<dyn CoreMeter>,
66
66
  pub default_attribs: NewAttributes,
67
+ pub task_queue_label_strategy: TaskQueueLabelStrategy,
67
68
  }
68
69
 
69
70
  impl Deref for TemporalMeter {
@@ -49,6 +49,9 @@ pub struct TelemetryOptions {
49
49
  /// all logging and traces.
50
50
  #[builder(setter(strip_option), default)]
51
51
  pub subscriber_override: Option<Arc<dyn Subscriber + Send + Sync>>,
52
+ /// See [TaskQueueLabelStrategy].
53
+ #[builder(default = "TaskQueueLabelStrategy::UseNormal")]
54
+ pub task_queue_label_strategy: TaskQueueLabelStrategy,
52
55
  }
53
56
  impl Debug for TelemetryOptions {
54
57
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
@@ -80,6 +83,16 @@ impl Debug for TelemetryOptions {
80
83
  }
81
84
  }
82
85
 
86
+ /// Determines how the `task_queue` label value is set on metrics.
87
+ #[derive(Copy, Clone, Debug)]
88
+ #[non_exhaustive]
89
+ pub enum TaskQueueLabelStrategy {
90
+ /// Always use the normal task queue name, including for actions relating to sticky queues.
91
+ UseNormal,
92
+ /// Use the sticky queue name when recording metrics operating on sticky queues.
93
+ UseNormalAndSticky,
94
+ }
95
+
83
96
  /// Options for exporting to an OpenTelemetry Collector
84
97
  #[derive(Debug, Clone, derive_builder::Builder)]
85
98
  pub struct OtelCollectorOptions {
@@ -10,22 +10,26 @@ crate-type = ["cdylib"]
10
10
  [dependencies]
11
11
  anyhow = "1.0"
12
12
  async-trait = "0.1"
13
+ crossbeam-utils = "0.8"
13
14
  futures-util = { version = "0.3", default-features = false }
14
- http = "1.1"
15
+ http = "1.3"
15
16
  libc = "0.2"
16
17
  prost = { workspace = true }
17
18
  # We rely on Cargo semver rules not updating a 0.x to 0.y. Per the rand
18
19
  # documentation, before 1.0, minor 0.x updates _can_ break portability which can
19
20
  # cause non-determinism.
20
- rand = "0.8.5"
21
- rand_pcg = "0.3.1"
21
+ rand = "0.9.2"
22
+ rand_pcg = "0.9.0"
23
+ serde = { version = "1.0", features = ["derive"] }
22
24
  serde_json = "1.0"
23
- tokio = "1.26"
25
+ tokio = "1.47"
24
26
  tokio-stream = "0.1"
25
27
  tokio-util = "0.7"
26
28
  tonic = { workspace = true }
27
29
  tracing = "0.1"
28
- url = "2.2"
30
+ url = "2.5"
31
+ # This is only needed as an explicit dependency so we can enable static as a feature
32
+ xz2 = { version = "0.1" }
29
33
 
30
34
  [dependencies.temporal-client]
31
35
  path = "../client"
@@ -36,6 +40,7 @@ features = ["ephemeral-server"]
36
40
 
37
41
  [dependencies.temporal-sdk-core-api]
38
42
  path = "../core-api"
43
+ features = ["envconfig"]
39
44
 
40
45
  [dependencies.temporal-sdk-core-protos]
41
46
  path = "../sdk-core-protos"
@@ -44,8 +49,8 @@ path = "../sdk-core-protos"
44
49
  futures-util = "0.3"
45
50
  thiserror = { workspace = true }
46
51
 
47
- [dev-dependencies.temporal-sdk-core-test-utils]
48
- path = "../test-utils"
49
-
50
52
  [build-dependencies]
51
53
  cbindgen = { version = "0.29", default-features = false }
54
+
55
+ [features]
56
+ xz2-static = ["xz2/static"]