@temporalio/core-bridge 1.9.2 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/Cargo.lock +754 -473
  2. package/Cargo.toml +3 -3
  3. package/lib/index.d.ts +33 -2
  4. package/lib/index.js.map +1 -1
  5. package/package.json +4 -4
  6. package/releases/aarch64-apple-darwin/index.node +0 -0
  7. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  8. package/releases/x86_64-apple-darwin/index.node +0 -0
  9. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  10. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  11. package/scripts/build.js +4 -3
  12. package/sdk-core/.cargo/config.toml +2 -4
  13. package/sdk-core/.github/workflows/heavy.yml +1 -1
  14. package/sdk-core/.github/workflows/per-pr.yml +6 -4
  15. package/sdk-core/Cargo.toml +10 -3
  16. package/sdk-core/README.md +4 -6
  17. package/sdk-core/client/Cargo.toml +13 -5
  18. package/sdk-core/client/src/lib.rs +123 -34
  19. package/sdk-core/client/src/metrics.rs +70 -18
  20. package/sdk-core/client/src/proxy.rs +85 -0
  21. package/sdk-core/client/src/raw.rs +67 -5
  22. package/sdk-core/client/src/worker_registry/mod.rs +5 -3
  23. package/sdk-core/client/src/workflow_handle/mod.rs +3 -1
  24. package/sdk-core/core/Cargo.toml +31 -37
  25. package/sdk-core/core/src/abstractions/take_cell.rs +3 -3
  26. package/sdk-core/core/src/abstractions.rs +176 -108
  27. package/sdk-core/core/src/core_tests/activity_tasks.rs +4 -13
  28. package/sdk-core/core/src/core_tests/determinism.rs +2 -1
  29. package/sdk-core/core/src/core_tests/local_activities.rs +3 -3
  30. package/sdk-core/core/src/core_tests/mod.rs +3 -3
  31. package/sdk-core/core/src/core_tests/queries.rs +42 -5
  32. package/sdk-core/core/src/core_tests/workers.rs +2 -3
  33. package/sdk-core/core/src/core_tests/workflow_tasks.rs +115 -15
  34. package/sdk-core/core/src/ephemeral_server/mod.rs +109 -136
  35. package/sdk-core/core/src/internal_flags.rs +8 -8
  36. package/sdk-core/core/src/lib.rs +16 -11
  37. package/sdk-core/core/src/pollers/mod.rs +11 -5
  38. package/sdk-core/core/src/pollers/poll_buffer.rs +48 -29
  39. package/sdk-core/core/src/protosext/mod.rs +32 -32
  40. package/sdk-core/core/src/protosext/protocol_messages.rs +14 -24
  41. package/sdk-core/core/src/retry_logic.rs +2 -2
  42. package/sdk-core/core/src/telemetry/log_export.rs +10 -9
  43. package/sdk-core/core/src/telemetry/metrics.rs +233 -330
  44. package/sdk-core/core/src/telemetry/mod.rs +11 -38
  45. package/sdk-core/core/src/telemetry/otel.rs +355 -0
  46. package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -23
  47. package/sdk-core/core/src/test_help/mod.rs +80 -59
  48. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +6 -6
  49. package/sdk-core/core/src/worker/activities/local_activities.rs +46 -43
  50. package/sdk-core/core/src/worker/activities.rs +45 -46
  51. package/sdk-core/core/src/worker/client/mocks.rs +8 -7
  52. package/sdk-core/core/src/worker/client.rs +40 -39
  53. package/sdk-core/core/src/worker/mod.rs +72 -42
  54. package/sdk-core/core/src/worker/slot_provider.rs +28 -28
  55. package/sdk-core/core/src/worker/slot_supplier.rs +1 -0
  56. package/sdk-core/core/src/worker/tuner/fixed_size.rs +52 -0
  57. package/sdk-core/core/src/worker/tuner/resource_based.rs +561 -0
  58. package/sdk-core/core/src/worker/tuner.rs +122 -0
  59. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +6 -6
  60. package/sdk-core/core/src/worker/workflow/history_update.rs +27 -53
  61. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +4 -17
  62. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -10
  63. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +4 -11
  64. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +17 -35
  65. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -8
  66. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -5
  67. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -5
  68. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -5
  69. package/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -14
  70. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -5
  71. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -5
  72. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -10
  73. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -10
  74. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +12 -8
  75. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +0 -10
  76. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -13
  77. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +27 -37
  78. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +3 -14
  79. package/sdk-core/core/src/worker/workflow/managed_run.rs +84 -54
  80. package/sdk-core/core/src/worker/workflow/mod.rs +63 -160
  81. package/sdk-core/core/src/worker/workflow/run_cache.rs +22 -13
  82. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +16 -3
  83. package/sdk-core/core/src/worker/workflow/wft_poller.rs +15 -12
  84. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +39 -78
  85. package/sdk-core/core-api/Cargo.toml +6 -5
  86. package/sdk-core/core-api/src/errors.rs +8 -0
  87. package/sdk-core/core-api/src/telemetry/metrics.rs +75 -4
  88. package/sdk-core/core-api/src/telemetry.rs +7 -1
  89. package/sdk-core/core-api/src/worker.rs +212 -56
  90. package/sdk-core/fsm/Cargo.toml +3 -0
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  92. package/sdk-core/sdk/Cargo.toml +5 -7
  93. package/sdk-core/sdk/src/app_data.rs +3 -3
  94. package/sdk-core/sdk/src/lib.rs +5 -3
  95. package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
  96. package/sdk-core/sdk/src/workflow_context.rs +10 -9
  97. package/sdk-core/sdk/src/workflow_future.rs +1 -1
  98. package/sdk-core/sdk-core-protos/Cargo.toml +8 -6
  99. package/sdk-core/sdk-core-protos/build.rs +1 -10
  100. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +3 -0
  101. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/ci.yml +26 -0
  102. package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +42 -20
  103. package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +2 -0
  104. package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +36 -26
  105. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +2 -0
  106. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/struct.proto +95 -0
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +9632 -0
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +7337 -0
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/payload_description.txt +2 -0
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +45 -11
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +22 -4
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +2 -0
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +44 -0
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +18 -3
  115. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -0
  116. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +30 -0
  117. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +7 -8
  118. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +23 -5
  119. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +20 -0
  120. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +25 -0
  121. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +141 -15
  122. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +12 -0
  123. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +193 -0
  124. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +73 -6
  125. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +46 -4
  126. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +4 -0
  127. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +2 -2
  128. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +116 -0
  129. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +134 -0
  130. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +274 -29
  131. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +57 -1
  132. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +10 -12
  133. package/sdk-core/sdk-core-protos/src/history_builder.rs +1 -1
  134. package/sdk-core/sdk-core-protos/src/lib.rs +54 -51
  135. package/sdk-core/sdk-core-protos/src/task_token.rs +11 -2
  136. package/sdk-core/test-utils/Cargo.toml +7 -4
  137. package/sdk-core/test-utils/src/histfetch.rs +1 -1
  138. package/sdk-core/test-utils/src/lib.rs +44 -62
  139. package/sdk-core/tests/fuzzy_workflow.rs +5 -2
  140. package/sdk-core/tests/heavy_tests.rs +114 -17
  141. package/sdk-core/tests/integ_tests/activity_functions.rs +1 -1
  142. package/sdk-core/tests/integ_tests/client_tests.rs +2 -2
  143. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +38 -26
  144. package/sdk-core/tests/integ_tests/metrics_tests.rs +126 -17
  145. package/sdk-core/tests/integ_tests/polling_tests.rs +118 -2
  146. package/sdk-core/tests/integ_tests/update_tests.rs +3 -5
  147. package/sdk-core/tests/integ_tests/visibility_tests.rs +3 -3
  148. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +1 -1
  149. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
  150. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
  151. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  152. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +3 -3
  153. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -4
  154. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -2
  155. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +6 -10
  156. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +9 -7
  157. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -1
  158. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +14 -9
  159. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
  160. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +6 -13
  161. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +9 -6
  162. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +5 -5
  163. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
  164. package/sdk-core/tests/integ_tests/workflow_tests.rs +115 -11
  165. package/sdk-core/tests/main.rs +2 -2
  166. package/src/conversions.rs +57 -0
  167. package/src/lib.rs +1 -0
  168. package/src/runtime.rs +51 -35
  169. package/ts/index.ts +67 -3
  170. package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  171. package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  172. package/sdk-core/sdk/src/payload_converter.rs +0 -11
  173. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +0 -2
  174. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/docker-compose.yml +0 -15
  175. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/pipeline.yml +0 -10
  176. package/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  177. package/sdk-core/tests/wf_input_replay.rs +0 -32
@@ -9,7 +9,7 @@ pub(crate) use local_activities::{
9
9
 
10
10
  use crate::{
11
11
  abstractions::{
12
- ClosableMeteredSemaphore, MeteredSemaphore, OwnedMeteredSemPermit,
12
+ ClosableMeteredPermitDealer, MeteredPermitDealer, OwnedMeteredSemPermit,
13
13
  TrackedOwnedMeteredSemPermit, UsedMeteredSemPermit,
14
14
  },
15
15
  pollers::BoxedActPoller,
@@ -39,6 +39,7 @@ use std::{
39
39
  },
40
40
  time::{Duration, Instant},
41
41
  };
42
+ use temporal_sdk_core_api::worker::{ActivitySlotInfo, ActivitySlotKind};
42
43
  use temporal_sdk_core_protos::{
43
44
  coresdk::{
44
45
  activity_result::{self as ar, activity_execution_result as aer},
@@ -73,7 +74,7 @@ struct PendingActivityCancel {
73
74
  }
74
75
 
75
76
  impl PendingActivityCancel {
76
- pub fn new(task_token: TaskToken, reason: ActivityCancelReason) -> Self {
77
+ fn new(task_token: TaskToken, reason: ActivityCancelReason) -> Self {
77
78
  Self {
78
79
  task_token,
79
80
  reason,
@@ -85,36 +86,39 @@ impl PendingActivityCancel {
85
86
  /// Contains details that core wants to store while an activity is running.
86
87
  #[derive(Debug)]
87
88
  struct InFlightActInfo {
88
- pub activity_type: String,
89
- pub workflow_type: String,
89
+ activity_type: String,
90
+ workflow_type: String,
90
91
  /// Only kept for logging reasons
91
- pub workflow_id: String,
92
+ workflow_id: String,
92
93
  /// Only kept for logging reasons
93
- pub workflow_run_id: String,
94
+ workflow_run_id: String,
94
95
  start_time: Instant,
95
96
  }
96
97
 
97
98
  /// Augments [InFlightActInfo] with details specific to remote activities
98
99
  struct RemoteInFlightActInfo {
99
- pub base: InFlightActInfo,
100
+ base: InFlightActInfo,
100
101
  /// Used to calculate aggregation delay between activity heartbeats.
101
- pub heartbeat_timeout: Option<prost_types::Duration>,
102
+ heartbeat_timeout: Option<prost_types::Duration>,
102
103
  /// Set if we have already issued a cancellation activation to lang for this activity, with
103
104
  /// the original reason we issued the cancel.
104
- pub issued_cancel_to_lang: Option<ActivityCancelReason>,
105
+ issued_cancel_to_lang: Option<ActivityCancelReason>,
105
106
  /// Set to true if we have already learned from the server this activity doesn't exist. EX:
106
107
  /// we have learned from heartbeating and issued a cancel task, in which case we may simply
107
108
  /// discard the reply.
108
- pub known_not_found: bool,
109
+ known_not_found: bool,
109
110
  /// Handle to the task containing local timeout tracking, if any.
110
- pub local_timeouts_task: Option<JoinHandle<()>>,
111
+ local_timeouts_task: Option<JoinHandle<()>>,
111
112
  /// Used to reset the local heartbeat timeout every time we record a heartbeat
112
113
  timeout_resetter: Option<Arc<Notify>>,
113
114
  /// The permit from the max concurrent semaphore
114
- _permit: UsedMeteredSemPermit,
115
+ _permit: UsedMeteredSemPermit<ActivitySlotKind>,
115
116
  }
116
117
  impl RemoteInFlightActInfo {
117
- fn new(poll_resp: &PollActivityTaskQueueResponse, permit: UsedMeteredSemPermit) -> Self {
118
+ fn new(
119
+ poll_resp: &PollActivityTaskQueueResponse,
120
+ permit: UsedMeteredSemPermit<ActivitySlotKind>,
121
+ ) -> Self {
118
122
  let wec = poll_resp.workflow_execution.clone().unwrap_or_default();
119
123
  Self {
120
124
  base: InFlightActInfo {
@@ -146,8 +150,8 @@ pub(crate) struct WorkerActivityTasks {
146
150
  outstanding_activity_tasks: OutstandingActMap,
147
151
  /// Ensures we don't exceed this worker's maximum concurrent activity limit for activities. This
148
152
  /// semaphore is used to limit eager activities but shares the same underlying
149
- /// [MeteredSemaphore] that is used to limit the concurrency for non-eager activities.
150
- eager_activities_semaphore: Arc<ClosableMeteredSemaphore>,
153
+ /// [MeteredPermitDealer] that is used to limit the concurrency for non-eager activities.
154
+ eager_activities_semaphore: Arc<ClosableMeteredPermitDealer<ActivitySlotKind>>,
151
155
  /// Holds activity tasks we have received in direct response to workflow task completion (a.k.a
152
156
  /// eager activities). Tasks received in this stream hold a "tracked" permit that is issued by
153
157
  /// the `eager_activities_semaphore`.
@@ -176,7 +180,7 @@ enum ActivityTaskSource {
176
180
  impl WorkerActivityTasks {
177
181
  #[allow(clippy::too_many_arguments)]
178
182
  pub(crate) fn new(
179
- semaphore: Arc<MeteredSemaphore>,
183
+ semaphore: Arc<MeteredPermitDealer<ActivitySlotKind>>,
180
184
  poller: BoxedActPoller,
181
185
  client: Arc<dyn WorkerClient>,
182
186
  metrics: MetricsContext,
@@ -190,7 +194,7 @@ impl WorkerActivityTasks {
190
194
  let server_poller_stream =
191
195
  new_activity_task_poller(poller, metrics.clone(), shutdown_initiated_token.clone());
192
196
  let (eager_activities_tx, eager_activities_rx) = unbounded_channel();
193
- let eager_activities_semaphore = ClosableMeteredSemaphore::new_arc(semaphore);
197
+ let eager_activities_semaphore = ClosableMeteredPermitDealer::new_arc(semaphore);
194
198
 
195
199
  let start_tasks_stream_complete = CancellationToken::new();
196
200
  let starts_stream = Self::merge_start_task_sources(
@@ -241,7 +245,7 @@ impl WorkerActivityTasks {
241
245
  fn merge_start_task_sources(
242
246
  non_poll_tasks_rx: UnboundedReceiver<TrackedPermittedTqResp>,
243
247
  poller_stream: impl Stream<Item = Result<PermittedTqResp, tonic::Status>>,
244
- eager_activities_semaphore: Arc<ClosableMeteredSemaphore>,
248
+ eager_activities_semaphore: Arc<ClosableMeteredPermitDealer<ActivitySlotKind>>,
245
249
  on_complete_token: CancellationToken,
246
250
  ) -> impl Stream<Item = Result<(PermittedTqResp, bool), PollActivityError>> {
247
251
  let non_poll_stream = stream::unfold(
@@ -444,7 +448,7 @@ impl WorkerActivityTasks {
444
448
  }
445
449
 
446
450
  #[cfg(test)]
447
- pub(crate) fn remaining_activity_capacity(&self) -> usize {
451
+ pub(crate) fn remaining_activity_capacity(&self) -> Option<usize> {
448
452
  self.eager_activities_semaphore.unused_permits()
449
453
  }
450
454
  }
@@ -512,11 +516,13 @@ where
512
516
  }
513
517
  ActivityTaskSource::PendingStart(res) => {
514
518
  Some(res.map(|(task, is_eager)| {
519
+ let mut activity_type_name = "";
515
520
  if let Some(ref act_type) = task.resp.activity_type {
521
+ activity_type_name = act_type.name.as_str();
516
522
  if let Some(ref wf_type) = task.resp.workflow_type {
517
523
  self.metrics
518
524
  .with_new_attrs([
519
- activity_type(act_type.name.clone()),
525
+ activity_type(activity_type_name.to_owned()),
520
526
  workflow_type(wf_type.name.clone()),
521
527
  eager(is_eager),
522
528
  ])
@@ -533,9 +539,13 @@ where
533
539
 
534
540
  let tt: TaskToken = task.resp.task_token.clone().into();
535
541
  let outstanding_entry = self.outstanding_tasks.entry(tt.clone());
536
- let mut outstanding_info = outstanding_entry.insert(
537
- RemoteInFlightActInfo::new(&task.resp, task.permit.into_used()),
538
- );
542
+ let mut outstanding_info =
543
+ outstanding_entry.insert(RemoteInFlightActInfo::new(
544
+ &task.resp,
545
+ task.permit.into_used(ActivitySlotInfo {
546
+ activity_type: activity_type_name,
547
+ }),
548
+ ));
539
549
  // If we have already waited the grace period and issued cancels,
540
550
  // this will have been set true, indicating anything that happened
541
551
  // to be buffered/in-flight/etc should get an immediate cancel. This
@@ -641,14 +651,14 @@ where
641
651
  /// Provides facilities for the workflow side of things to interact with the activity manager.
642
652
  /// Allows for the handling of activities returned by WFT completions.
643
653
  pub(crate) struct ActivitiesFromWFTsHandle {
644
- sem: Arc<ClosableMeteredSemaphore>,
654
+ sem: Arc<ClosableMeteredPermitDealer<ActivitySlotKind>>,
645
655
  tx: UnboundedSender<TrackedPermittedTqResp>,
646
656
  }
647
657
 
648
658
  impl ActivitiesFromWFTsHandle {
649
659
  /// Returns a handle that can be used to reserve an activity slot. EX: When requesting eager
650
660
  /// dispatch of an activity to this worker upon workflow task completion
651
- pub(crate) fn reserve_slot(&self) -> Option<TrackedOwnedMeteredSemPermit> {
661
+ pub(crate) fn reserve_slot(&self) -> Option<TrackedOwnedMeteredSemPermit<ActivitySlotKind>> {
652
662
  // TODO: check if rate limit is not exceeded and count this reservation towards the rate limit
653
663
  self.sem.try_acquire_owned().ok()
654
664
  }
@@ -666,14 +676,14 @@ impl ActivitiesFromWFTsHandle {
666
676
 
667
677
  #[derive(Debug)]
668
678
  pub(crate) struct PermittedTqResp {
669
- pub permit: OwnedMeteredSemPermit,
670
- pub resp: PollActivityTaskQueueResponse,
679
+ pub(crate) permit: OwnedMeteredSemPermit<ActivitySlotKind>,
680
+ pub(crate) resp: PollActivityTaskQueueResponse,
671
681
  }
672
682
 
673
683
  #[derive(Debug)]
674
684
  pub(crate) struct TrackedPermittedTqResp {
675
- pub permit: TrackedOwnedMeteredSemPermit,
676
- pub resp: PollActivityTaskQueueResponse,
685
+ pub(crate) permit: TrackedOwnedMeteredSemPermit<ActivitySlotKind>,
686
+ pub(crate) resp: PollActivityTaskQueueResponse,
677
687
  }
678
688
 
679
689
  fn worker_shutdown_failure() -> Failure {
@@ -687,7 +697,7 @@ fn worker_shutdown_failure() -> Failure {
687
697
  ApplicationFailureInfo {
688
698
  r#type: "WorkerShutdown".to_string(),
689
699
  non_retryable: false,
690
- details: None,
700
+ ..Default::default()
691
701
  },
692
702
  )),
693
703
  }
@@ -697,7 +707,8 @@ fn worker_shutdown_failure() -> Failure {
697
707
  mod tests {
698
708
  use super::*;
699
709
  use crate::{
700
- pollers::new_activity_task_buffer, prost_dur, worker::client::mocks::mock_workflow_client,
710
+ abstractions::tests::fixed_size_permit_dealer, pollers::new_activity_task_buffer,
711
+ prost_dur, worker::client::mocks::mock_workflow_client,
701
712
  };
702
713
  use temporal_sdk_core_protos::coresdk::activity_result::ActivityExecutionResult;
703
714
 
@@ -729,11 +740,7 @@ mod tests {
729
740
  .times(2)
730
741
  .returning(|_, _| Ok(Default::default()));
731
742
  let mock_client = Arc::new(mock_client);
732
- let sem = Arc::new(MeteredSemaphore::new(
733
- 10,
734
- MetricsContext::no_op(),
735
- MetricsContext::available_task_slots,
736
- ));
743
+ let sem = Arc::new(fixed_size_permit_dealer(10));
737
744
  let shutdown_token = CancellationToken::new();
738
745
  let ap = new_activity_task_buffer(
739
746
  mock_client.clone(),
@@ -822,11 +829,7 @@ mod tests {
822
829
  })
823
830
  });
824
831
  let mock_client = Arc::new(mock_client);
825
- let sem = Arc::new(MeteredSemaphore::new(
826
- 1, // Just one task at a time
827
- MetricsContext::no_op(),
828
- MetricsContext::available_task_slots,
829
- ));
832
+ let sem = Arc::new(fixed_size_permit_dealer(1));
830
833
  let shutdown_token = CancellationToken::new();
831
834
  let ap = new_activity_task_buffer(
832
835
  mock_client.clone(),
@@ -897,11 +900,7 @@ mod tests {
897
900
  .times(2)
898
901
  .returning(|_, _| Ok(Default::default()));
899
902
  let mock_client = Arc::new(mock_client);
900
- let sem = Arc::new(MeteredSemaphore::new(
901
- 1, // Just one task at a time
902
- MetricsContext::no_op(),
903
- MetricsContext::available_task_slots,
904
- ));
903
+ let sem = Arc::new(fixed_size_permit_dealer(1));
905
904
  let shutdown_token = CancellationToken::new();
906
905
  let ap = new_activity_task_buffer(
907
906
  mock_client.clone(),
@@ -1,12 +1,11 @@
1
1
  use super::*;
2
2
  use futures::Future;
3
- use lazy_static::lazy_static;
3
+ use once_cell::sync::Lazy;
4
4
  use std::sync::Arc;
5
5
  use temporal_client::SlotManager;
6
6
 
7
- lazy_static! {
8
- pub(crate) static ref DEFAULT_WORKERS_REGISTRY: Arc<SlotManager> = Arc::new(SlotManager::new());
9
- }
7
+ static DEFAULT_WORKERS_REGISTRY: Lazy<Arc<SlotManager>> =
8
+ Lazy::new(|| Arc::new(SlotManager::new()));
10
9
 
11
10
  pub(crate) static DEFAULT_TEST_CAPABILITIES: &Capabilities = &Capabilities {
12
11
  signal_and_query_header: true,
@@ -26,7 +25,7 @@ pub(crate) static DEFAULT_TEST_CAPABILITIES: &Capabilities = &Capabilities {
26
25
  pub(crate) fn mock_workflow_client() -> MockWorkerClient {
27
26
  let mut r = MockWorkerClient::new();
28
27
  r.expect_capabilities()
29
- .returning(|| Some(DEFAULT_TEST_CAPABILITIES));
28
+ .returning(|| Some(DEFAULT_TEST_CAPABILITIES.clone()));
30
29
  r.expect_workers()
31
30
  .returning(|| DEFAULT_WORKERS_REGISTRY.clone());
32
31
  r.expect_is_mock().returning(|| true);
@@ -37,7 +36,7 @@ pub(crate) fn mock_workflow_client() -> MockWorkerClient {
37
36
  pub(crate) fn mock_manual_workflow_client() -> MockManualWorkerClient {
38
37
  let mut r = MockManualWorkerClient::new();
39
38
  r.expect_capabilities()
40
- .returning(|| Some(DEFAULT_TEST_CAPABILITIES));
39
+ .returning(|| Some(DEFAULT_TEST_CAPABILITIES.clone()));
41
40
  r.expect_workers()
42
41
  .returning(|| DEFAULT_WORKERS_REGISTRY.clone());
43
42
  r.expect_is_mock().returning(|| true);
@@ -116,7 +115,9 @@ mockall::mock! {
116
115
  ) -> impl Future<Output = Result<RespondQueryTaskCompletedResponse>> + Send + 'b
117
116
  where 'a: 'b, Self: 'b;
118
117
 
119
- fn capabilities(&self) -> Option<&'static get_system_info_response::Capabilities>;
118
+ fn replace_client(&self, new_client: RetryClient<Client>);
119
+
120
+ fn capabilities(&self) -> Option<get_system_info_response::Capabilities>;
120
121
 
121
122
  fn workers(&self) -> Arc<SlotManager>;
122
123
 
@@ -1,6 +1,7 @@
1
1
  //! Worker-specific client needs
2
2
 
3
3
  pub(crate) mod mocks;
4
+ use parking_lot::RwLock;
4
5
  use std::sync::Arc;
5
6
  use temporal_client::{Client, RetryClient, SlotManager, WorkflowService};
6
7
  use temporal_sdk_core_protos::{
@@ -26,7 +27,7 @@ type Result<T, E = tonic::Status> = std::result::Result<T, E>;
26
27
 
27
28
  /// Contains everything a worker needs to interact with the server
28
29
  pub(crate) struct WorkerClientBag {
29
- client: RetryClient<Client>,
30
+ replaceable_client: RwLock<RetryClient<Client>>,
30
31
  namespace: String,
31
32
  identity: String,
32
33
  worker_build_id: String,
@@ -34,7 +35,7 @@ pub(crate) struct WorkerClientBag {
34
35
  }
35
36
 
36
37
  impl WorkerClientBag {
37
- pub fn new(
38
+ pub(crate) fn new(
38
39
  client: RetryClient<Client>,
39
40
  namespace: String,
40
41
  identity: String,
@@ -42,7 +43,7 @@ impl WorkerClientBag {
42
43
  use_versioning: bool,
43
44
  ) -> Self {
44
45
  Self {
45
- client,
46
+ replaceable_client: RwLock::new(client),
46
47
  namespace,
47
48
  identity,
48
49
  worker_build_id,
@@ -50,8 +51,12 @@ impl WorkerClientBag {
50
51
  }
51
52
  }
52
53
 
54
+ fn cloned_client(&self) -> RetryClient<Client> {
55
+ self.replaceable_client.read().clone()
56
+ }
57
+
53
58
  fn default_capabilities(&self) -> Capabilities {
54
- self.capabilities().cloned().unwrap_or_default()
59
+ self.capabilities().unwrap_or_default()
55
60
  }
56
61
 
57
62
  fn binary_checksum(&self) -> String {
@@ -77,7 +82,6 @@ impl WorkerClientBag {
77
82
  if self.default_capabilities().build_id_based_versioning {
78
83
  Some(WorkerVersionStamp {
79
84
  build_id: self.worker_build_id.clone(),
80
- bundle_id: "".to_string(),
81
85
  use_versioning: self.use_versioning,
82
86
  })
83
87
  } else {
@@ -142,8 +146,8 @@ pub(crate) trait WorkerClient: Sync + Send {
142
146
  query_result: QueryResult,
143
147
  ) -> Result<RespondQueryTaskCompletedResponse>;
144
148
 
145
- #[allow(clippy::needless_lifetimes)] // Clippy is wrong here
146
- fn capabilities<'a>(&'a self) -> Option<&'a get_system_info_response::Capabilities>;
149
+ fn replace_client(&self, new_client: RetryClient<Client>);
150
+ fn capabilities(&self) -> Option<get_system_info_response::Capabilities>;
147
151
  fn workers(&self) -> Arc<SlotManager>;
148
152
  fn is_mock(&self) -> bool;
149
153
  }
@@ -163,8 +167,7 @@ impl WorkerClient for WorkerClientBag {
163
167
  };
164
168
 
165
169
  Ok(self
166
- .client
167
- .clone()
170
+ .cloned_client()
168
171
  .poll_workflow_task_queue(request)
169
172
  .await?
170
173
  .into_inner())
@@ -190,8 +193,7 @@ impl WorkerClient for WorkerClientBag {
190
193
  };
191
194
 
192
195
  Ok(self
193
- .client
194
- .clone()
196
+ .cloned_client()
195
197
  .poll_activity_task_queue(request)
196
198
  .await?
197
199
  .into_inner())
@@ -231,8 +233,7 @@ impl WorkerClient for WorkerClientBag {
231
233
  metering_metadata: Some(request.metering_metadata),
232
234
  };
233
235
  Ok(self
234
- .client
235
- .clone()
236
+ .cloned_client()
236
237
  .respond_workflow_task_completed(request)
237
238
  .await?
238
239
  .into_inner())
@@ -244,8 +245,7 @@ impl WorkerClient for WorkerClientBag {
244
245
  result: Option<Payloads>,
245
246
  ) -> Result<RespondActivityTaskCompletedResponse> {
246
247
  Ok(self
247
- .client
248
- .clone()
248
+ .cloned_client()
249
249
  .respond_activity_task_completed(RespondActivityTaskCompletedRequest {
250
250
  task_token: task_token.0,
251
251
  result,
@@ -263,8 +263,7 @@ impl WorkerClient for WorkerClientBag {
263
263
  details: Option<Payloads>,
264
264
  ) -> Result<RecordActivityTaskHeartbeatResponse> {
265
265
  Ok(self
266
- .client
267
- .clone()
266
+ .cloned_client()
268
267
  .record_activity_task_heartbeat(RecordActivityTaskHeartbeatRequest {
269
268
  task_token: task_token.0,
270
269
  details,
@@ -281,8 +280,7 @@ impl WorkerClient for WorkerClientBag {
281
280
  details: Option<Payloads>,
282
281
  ) -> Result<RespondActivityTaskCanceledResponse> {
283
282
  Ok(self
284
- .client
285
- .clone()
283
+ .cloned_client()
286
284
  .respond_activity_task_canceled(RespondActivityTaskCanceledRequest {
287
285
  task_token: task_token.0,
288
286
  details,
@@ -300,8 +298,7 @@ impl WorkerClient for WorkerClientBag {
300
298
  failure: Option<Failure>,
301
299
  ) -> Result<RespondActivityTaskFailedResponse> {
302
300
  Ok(self
303
- .client
304
- .clone()
301
+ .cloned_client()
305
302
  .respond_activity_task_failed(RespondActivityTaskFailedRequest {
306
303
  task_token: task_token.0,
307
304
  failure,
@@ -332,8 +329,7 @@ impl WorkerClient for WorkerClientBag {
332
329
  worker_version: self.worker_version_stamp(),
333
330
  };
334
331
  Ok(self
335
- .client
336
- .clone()
332
+ .cloned_client()
337
333
  .respond_workflow_task_failed(request)
338
334
  .await?
339
335
  .into_inner())
@@ -346,8 +342,7 @@ impl WorkerClient for WorkerClientBag {
346
342
  page_token: Vec<u8>,
347
343
  ) -> Result<GetWorkflowExecutionHistoryResponse> {
348
344
  Ok(self
349
- .client
350
- .clone()
345
+ .cloned_client()
351
346
  .get_workflow_execution_history(GetWorkflowExecutionHistoryRequest {
352
347
  namespace: self.namespace.clone(),
353
348
  execution: Some(WorkflowExecution {
@@ -368,8 +363,7 @@ impl WorkerClient for WorkerClientBag {
368
363
  ) -> Result<RespondQueryTaskCompletedResponse> {
369
364
  let (_, completed_type, query_result, error_message) = query_result.into_components();
370
365
  Ok(self
371
- .client
372
- .clone()
366
+ .cloned_client()
373
367
  .respond_query_task_completed(RespondQueryTaskCompletedRequest {
374
368
  task_token: task_token.into(),
375
369
  completed_type: completed_type as i32,
@@ -381,12 +375,19 @@ impl WorkerClient for WorkerClientBag {
381
375
  .into_inner())
382
376
  }
383
377
 
384
- fn capabilities(&self) -> Option<&Capabilities> {
385
- self.client.get_client().inner().capabilities()
378
+ fn replace_client(&self, new_client: RetryClient<Client>) {
379
+ let mut replaceable_client = self.replaceable_client.write();
380
+ *replaceable_client = new_client;
381
+ }
382
+
383
+ fn capabilities(&self) -> Option<Capabilities> {
384
+ let client = self.replaceable_client.read();
385
+ client.get_client().inner().capabilities().cloned()
386
386
  }
387
387
 
388
388
  fn workers(&self) -> Arc<SlotManager> {
389
- self.client.get_client().inner().workers()
389
+ let client = self.replaceable_client.read();
390
+ client.get_client().inner().workers()
390
391
  }
391
392
 
392
393
  fn is_mock(&self) -> bool {
@@ -399,21 +400,21 @@ impl WorkerClient for WorkerClientBag {
399
400
  #[derive(Debug, Clone, PartialEq)]
400
401
  pub(crate) struct WorkflowTaskCompletion {
401
402
  /// The task token that would've been received from polling for a workflow activation
402
- pub task_token: TaskToken,
403
+ pub(crate) task_token: TaskToken,
403
404
  /// A list of new commands to send to the server, such as starting a timer.
404
- pub commands: Vec<Command>,
405
+ pub(crate) commands: Vec<Command>,
405
406
  /// A list of protocol messages to send to the server.
406
- pub messages: Vec<ProtocolMessage>,
407
+ pub(crate) messages: Vec<ProtocolMessage>,
407
408
  /// If set, indicate that next task should be queued on sticky queue with given attributes.
408
- pub sticky_attributes: Option<StickyExecutionAttributes>,
409
+ pub(crate) sticky_attributes: Option<StickyExecutionAttributes>,
409
410
  /// Responses to queries in the `queries` field of the workflow task.
410
- pub query_responses: Vec<QueryResult>,
411
+ pub(crate) query_responses: Vec<QueryResult>,
411
412
  /// Indicate that the task completion should return a new WFT if one is available
412
- pub return_new_workflow_task: bool,
413
+ pub(crate) return_new_workflow_task: bool,
413
414
  /// Force a new WFT to be created after this completion
414
- pub force_create_new_workflow_task: bool,
415
+ pub(crate) force_create_new_workflow_task: bool,
415
416
  /// SDK-specific metadata to send
416
- pub sdk_metadata: WorkflowTaskCompletedMetadata,
417
+ pub(crate) sdk_metadata: WorkflowTaskCompletedMetadata,
417
418
  /// Metering info
418
- pub metering_metadata: MeteringMetadata,
419
+ pub(crate) metering_metadata: MeteringMetadata,
419
420
  }