@temporalio/core-bridge 1.1.0 → 1.4.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 (124) hide show
  1. package/Cargo.lock +765 -128
  2. package/Cargo.toml +2 -2
  3. package/common.js +7 -3
  4. package/index.d.ts +118 -5
  5. package/index.js +2 -6
  6. package/package.json +2 -3
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/releases/x86_64-apple-darwin/index.node +0 -0
  10. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  11. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  12. package/scripts/build.js +4 -3
  13. package/sdk-core/.buildkite/docker/Dockerfile +2 -1
  14. package/sdk-core/.buildkite/pipeline.yml +2 -0
  15. package/sdk-core/.cargo/config.toml +1 -1
  16. package/sdk-core/ARCHITECTURE.md +2 -2
  17. package/sdk-core/README.md +12 -0
  18. package/sdk-core/bridge-ffi/Cargo.toml +2 -2
  19. package/sdk-core/bridge-ffi/src/lib.rs +2 -2
  20. package/sdk-core/client/Cargo.toml +7 -5
  21. package/sdk-core/client/src/lib.rs +354 -226
  22. package/sdk-core/client/src/metrics.rs +13 -11
  23. package/sdk-core/client/src/raw.rs +352 -107
  24. package/sdk-core/client/src/retry.rs +188 -147
  25. package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
  26. package/sdk-core/core/Cargo.toml +28 -15
  27. package/sdk-core/core/src/core_tests/activity_tasks.rs +98 -33
  28. package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
  29. package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
  30. package/sdk-core/core/src/core_tests/workers.rs +3 -2
  31. package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
  32. package/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
  33. package/sdk-core/core/src/lib.rs +62 -28
  34. package/sdk-core/core/src/pollers/mod.rs +2 -0
  35. package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
  36. package/sdk-core/core/src/replay/mod.rs +3 -3
  37. package/sdk-core/core/src/retry_logic.rs +10 -9
  38. package/sdk-core/core/src/telemetry/metrics.rs +48 -39
  39. package/sdk-core/core/src/telemetry/mod.rs +46 -12
  40. package/sdk-core/core/src/telemetry/prometheus_server.rs +17 -13
  41. package/sdk-core/core/src/test_help/mod.rs +18 -8
  42. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
  43. package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
  44. package/sdk-core/core/src/worker/activities.rs +6 -12
  45. package/sdk-core/core/src/worker/client/mocks.rs +1 -0
  46. package/sdk-core/core/src/worker/client.rs +193 -64
  47. package/sdk-core/core/src/worker/mod.rs +14 -19
  48. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
  49. package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
  50. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
  51. package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
  52. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
  53. package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
  54. package/sdk-core/core/src/worker/workflow/mod.rs +62 -58
  55. package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
  56. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
  57. package/sdk-core/core-api/Cargo.toml +3 -3
  58. package/sdk-core/core-api/src/errors.rs +3 -11
  59. package/sdk-core/core-api/src/worker.rs +7 -0
  60. package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
  61. package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
  62. package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
  63. package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
  64. package/sdk-core/protos/api_upstream/Makefile +2 -2
  65. package/sdk-core/protos/api_upstream/buf.yaml +1 -0
  66. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
  67. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
  68. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
  69. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
  70. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
  71. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
  72. package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
  73. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
  74. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
  75. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
  76. package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
  77. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
  78. package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
  79. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
  80. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
  81. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
  82. package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
  83. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
  84. package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
  85. package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
  86. package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
  87. package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
  88. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
  89. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
  90. package/sdk-core/sdk/Cargo.toml +2 -2
  91. package/sdk-core/sdk/src/lib.rs +2 -2
  92. package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
  93. package/sdk-core/sdk/src/workflow_context.rs +30 -6
  94. package/sdk-core/sdk/src/workflow_future.rs +4 -4
  95. package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
  96. package/sdk-core/sdk-core-protos/build.rs +9 -1
  97. package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
  98. package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
  99. package/sdk-core/test-utils/Cargo.toml +3 -3
  100. package/sdk-core/test-utils/src/canned_histories.rs +58 -0
  101. package/sdk-core/test-utils/src/lib.rs +35 -12
  102. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
  103. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
  104. package/sdk-core/tests/integ_tests/polling_tests.rs +2 -1
  105. package/sdk-core/tests/integ_tests/queries_tests.rs +5 -5
  106. package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
  107. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
  108. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  109. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
  110. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +2 -6
  111. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
  112. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
  113. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
  114. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +8 -2
  115. package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
  116. package/sdk-core/tests/load_tests.rs +2 -1
  117. package/sdk-core/tests/main.rs +17 -0
  118. package/sdk-core/tests/runner.rs +93 -0
  119. package/src/conversions.rs +157 -94
  120. package/src/helpers.rs +190 -0
  121. package/src/lib.rs +10 -912
  122. package/src/runtime.rs +436 -0
  123. package/src/testing.rs +67 -0
  124. package/src/worker.rs +465 -0
@@ -1,5 +1,5 @@
1
1
  use crate::{
2
- worker::{activities::PendingActivityCancel, client::WorkerClientBag},
2
+ worker::{activities::PendingActivityCancel, client::WorkerClient},
3
3
  TaskToken,
4
4
  };
5
5
  use futures::StreamExt;
@@ -304,7 +304,7 @@ impl HeartbeatStreamState {
304
304
  impl ActivityHeartbeatManager {
305
305
  /// Creates a new instance of an activity heartbeat manager and returns a handle to the user,
306
306
  /// which allows to send new heartbeats and initiate the shutdown.
307
- pub fn new(client: Arc<WorkerClientBag>) -> Self {
307
+ pub fn new(client: Arc<dyn WorkerClient>) -> Self {
308
308
  let (heartbeat_stream_state, heartbeat_tx_source, shutdown_token) =
309
309
  HeartbeatStreamState::new();
310
310
  let (cancels_tx, cancels_rx) = unbounded_channel();
@@ -425,7 +425,7 @@ mod test {
425
425
  .expect_record_activity_heartbeat()
426
426
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
427
427
  .times(2);
428
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
428
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
429
429
  let fake_task_token = vec![1, 2, 3];
430
430
  // Send 2 heartbeat requests for 20ms apart.
431
431
  // The first heartbeat should be sent right away, and
@@ -446,9 +446,9 @@ mod test {
446
446
  .expect_record_activity_heartbeat()
447
447
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
448
448
  .times(3);
449
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
449
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
450
450
  let fake_task_token = vec![1, 2, 3];
451
- // Heartbeats always get sent if recorded less frequently than the throttle intreval
451
+ // Heartbeats always get sent if recorded less frequently than the throttle interval
452
452
  for i in 0_u8..3 {
453
453
  record_heartbeat(&hm, fake_task_token.clone(), i, Duration::from_millis(10));
454
454
  sleep(Duration::from_millis(20)).await;
@@ -466,7 +466,7 @@ mod test {
466
466
  .expect_record_activity_heartbeat()
467
467
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
468
468
  .times(1);
469
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
469
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
470
470
  let fake_task_token = vec![1, 2, 3];
471
471
  // Send a whole bunch of heartbeats very fast. We should still only send one total.
472
472
  for i in 0_u8..50 {
@@ -485,7 +485,7 @@ mod test {
485
485
  .expect_record_activity_heartbeat()
486
486
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
487
487
  .times(2);
488
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
488
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
489
489
  let fake_task_token = vec![1, 2, 3];
490
490
  record_heartbeat(&hm, fake_task_token.clone(), 0, Duration::from_millis(100));
491
491
  sleep(Duration::from_millis(500)).await;
@@ -502,7 +502,7 @@ mod test {
502
502
  .expect_record_activity_heartbeat()
503
503
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
504
504
  .times(2);
505
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
505
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
506
506
  let fake_task_token = vec![1, 2, 3];
507
507
  record_heartbeat(&hm, fake_task_token.clone(), 0, Duration::from_millis(100));
508
508
  // Let it propagate
@@ -522,7 +522,7 @@ mod test {
522
522
  .expect_record_activity_heartbeat()
523
523
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
524
524
  .times(1);
525
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
525
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
526
526
  let fake_task_token = vec![1, 2, 3];
527
527
  record_heartbeat(&hm, fake_task_token.clone(), 0, Duration::from_millis(100));
528
528
  hm.evict(fake_task_token.clone().into()).await;
@@ -537,7 +537,7 @@ mod test {
537
537
  .expect_record_activity_heartbeat()
538
538
  .returning(|_, _| Ok(RecordActivityTaskHeartbeatResponse::default()))
539
539
  .times(0);
540
- let hm = ActivityHeartbeatManager::new(Arc::new(mock_client.into()));
540
+ let hm = ActivityHeartbeatManager::new(Arc::new(mock_client));
541
541
  hm.shutdown().await;
542
542
  match hm.record(
543
543
  ActivityHeartbeat {
@@ -389,8 +389,8 @@ impl LocalActivityManager {
389
389
  current_attempt_scheduled_time: Some(new_la.schedule_time.into()),
390
390
  started_time: Some(SystemTime::now().into()),
391
391
  attempt,
392
- schedule_to_close_timeout: schedule_to_close.map(Into::into),
393
- start_to_close_timeout: start_to_close.map(Into::into),
392
+ schedule_to_close_timeout: schedule_to_close.and_then(|d| d.try_into().ok()),
393
+ start_to_close_timeout: start_to_close.and_then(|d| d.try_into().ok()),
394
394
  heartbeat_timeout: None,
395
395
  retry_policy: Some(sa.retry_policy),
396
396
  is_local: true,
@@ -440,7 +440,7 @@ impl LocalActivityManager {
440
440
  // We want this to be reported, as the workflow will mark this
441
441
  // failure down, then start a timer for backoff.
442
442
  return LACompleteAction::LangDoesTimerBackoff(
443
- backoff_dur.into(),
443
+ backoff_dur.try_into().expect("backoff fits into proto"),
444
444
  info,
445
445
  );
446
446
  }
@@ -638,7 +638,7 @@ impl Drop for TimeoutBag {
638
638
  #[cfg(test)]
639
639
  mod tests {
640
640
  use super::*;
641
- use crate::protosext::LACloseTimeouts;
641
+ use crate::{prost_dur, protosext::LACloseTimeouts};
642
642
  use temporal_sdk_core_protos::temporal::api::{
643
643
  common::v1::RetryPolicy,
644
644
  failure::v1::{failure::FailureInfo, ApplicationFailureInfo, Failure},
@@ -764,9 +764,9 @@ mod tests {
764
764
  activity_id: 1.to_string(),
765
765
  attempt: 5,
766
766
  retry_policy: RetryPolicy {
767
- initial_interval: Some(Duration::from_secs(1).into()),
767
+ initial_interval: Some(prost_dur!(from_secs(1))),
768
768
  backoff_coefficient: 10.0,
769
- maximum_interval: Some(Duration::from_secs(10).into()),
769
+ maximum_interval: Some(prost_dur!(from_secs(10))),
770
770
  maximum_attempts: 10,
771
771
  non_retryable_error_types: vec![],
772
772
  },
@@ -799,9 +799,9 @@ mod tests {
799
799
  activity_id: "1".to_string(),
800
800
  attempt: 1,
801
801
  retry_policy: RetryPolicy {
802
- initial_interval: Some(Duration::from_secs(1).into()),
802
+ initial_interval: Some(prost_dur!(from_secs(1))),
803
803
  backoff_coefficient: 10.0,
804
- maximum_interval: Some(Duration::from_secs(10).into()),
804
+ maximum_interval: Some(prost_dur!(from_secs(10))),
805
805
  maximum_attempts: 10,
806
806
  non_retryable_error_types: vec!["TestError".to_string()],
807
807
  },
@@ -843,9 +843,9 @@ mod tests {
843
843
  activity_id: 1.to_string(),
844
844
  attempt: 5,
845
845
  retry_policy: RetryPolicy {
846
- initial_interval: Some(Duration::from_secs(10).into()),
846
+ initial_interval: Some(prost_dur!(from_secs(10))),
847
847
  backoff_coefficient: 1.0,
848
- maximum_interval: Some(Duration::from_secs(10).into()),
848
+ maximum_interval: Some(prost_dur!(from_secs(10))),
849
849
  maximum_attempts: 10,
850
850
  non_retryable_error_types: vec![],
851
851
  },
@@ -892,7 +892,7 @@ mod tests {
892
892
  activity_id: 1.to_string(),
893
893
  attempt: 5,
894
894
  retry_policy: RetryPolicy {
895
- initial_interval: Some(Duration::from_millis(10).into()),
895
+ initial_interval: Some(prost_dur!(from_millis(10))),
896
896
  backoff_coefficient: 1.0,
897
897
  ..Default::default()
898
898
  },
@@ -929,7 +929,7 @@ mod tests {
929
929
  activity_id: 1.to_string(),
930
930
  attempt: 5,
931
931
  retry_policy: RetryPolicy {
932
- initial_interval: Some(Duration::from_millis(10).into()),
932
+ initial_interval: Some(prost_dur!(from_millis(10))),
933
933
  backoff_coefficient: 1.0,
934
934
  ..Default::default()
935
935
  },
@@ -975,7 +975,7 @@ mod tests {
975
975
  activity_id: 1.to_string(),
976
976
  attempt: 5,
977
977
  retry_policy: RetryPolicy {
978
- initial_interval: Some(Duration::from_millis(10).into()),
978
+ initial_interval: Some(prost_dur!(from_millis(10))),
979
979
  backoff_coefficient: 1.0,
980
980
  ..Default::default()
981
981
  },
@@ -12,10 +12,9 @@ use crate::{
12
12
  pollers::BoxedActPoller,
13
13
  telemetry::metrics::{activity_type, activity_worker_type, workflow_type, MetricsContext},
14
14
  worker::{
15
- activities::activity_heartbeat_manager::ActivityHeartbeatError,
16
- client::{WorkerClient, WorkerClientBag},
15
+ activities::activity_heartbeat_manager::ActivityHeartbeatError, client::WorkerClient,
17
16
  },
18
- CompleteActivityError, PollActivityError, TaskToken,
17
+ PollActivityError, TaskToken,
19
18
  };
20
19
  use activity_heartbeat_manager::ActivityHeartbeatManager;
21
20
  use dashmap::DashMap;
@@ -136,7 +135,7 @@ impl WorkerActivityTasks {
136
135
  max_activity_tasks: usize,
137
136
  max_worker_act_per_sec: Option<f64>,
138
137
  poller: BoxedActPoller,
139
- client: Arc<WorkerClientBag>,
138
+ client: Arc<dyn WorkerClient>,
140
139
  metrics: MetricsContext,
141
140
  max_heartbeat_throttle_interval: Duration,
142
141
  default_heartbeat_throttle_interval: Duration,
@@ -232,7 +231,7 @@ impl WorkerActivityTasks {
232
231
  task_token: TaskToken,
233
232
  status: aer::Status,
234
233
  client: &dyn WorkerClient,
235
- ) -> Result<(), CompleteActivityError> {
234
+ ) {
236
235
  if let Some((_, act_info)) = self.outstanding_activity_tasks.remove(&task_token) {
237
236
  let act_metrics = self.metrics.with_new_attrs([
238
237
  activity_type(act_info.base.activity_type.clone()),
@@ -285,7 +284,7 @@ impl WorkerActivityTasks {
285
284
  completion. This may happen if the activity has already been cancelled but \
286
285
  completed anyway.");
287
286
  } else {
288
- return Err(e.into());
287
+ warn!(error=?e, "Network error while completing activity");
289
288
  };
290
289
  };
291
290
  };
@@ -295,7 +294,6 @@ impl WorkerActivityTasks {
295
294
  &task_token
296
295
  );
297
296
  }
298
- Ok(())
299
297
  }
300
298
 
301
299
  /// Attempt to record an activity heartbeat
@@ -446,15 +444,11 @@ mod tests {
446
444
  }
447
445
  .into(),
448
446
  ]);
449
- let client = WorkerClientBag::new(
450
- Box::new(mock_manual_workflow_client()),
451
- "fake_namespace".to_string(),
452
- );
453
447
  let atm = WorkerActivityTasks::new(
454
448
  10,
455
449
  Some(2.0),
456
450
  poller,
457
- Arc::new(client),
451
+ Arc::new(mock_manual_workflow_client()),
458
452
  MetricsContext::default(),
459
453
  Duration::from_secs(1),
460
454
  Duration::from_secs(1),
@@ -17,6 +17,7 @@ pub(crate) fn mock_manual_workflow_client() -> MockManualWorkerClient {
17
17
  // https://github.com/asomers/mockall/issues/189 to be fixed for it to go away.
18
18
  mockall::mock! {
19
19
  pub ManualWorkerClient {}
20
+ #[allow(unused)]
20
21
  impl WorkerClient for ManualWorkerClient {
21
22
  fn poll_workflow_task<'a, 'b>(&'a self, task_queue: String, is_sticky: bool)
22
23
  -> impl Future<Output = Result<PollWorkflowTaskQueueResponse>> + Send + 'b
@@ -2,66 +2,53 @@
2
2
 
3
3
  pub(crate) mod mocks;
4
4
 
5
- use std::{
6
- borrow::Borrow,
7
- ops::{Deref, DerefMut},
8
- };
9
- use temporal_client::{WorkflowClientTrait, WorkflowTaskCompletion, RETRYABLE_ERROR_CODES};
5
+ use temporal_client::{Client, RetryClient, WorkflowService, WorkflowTaskCompletion};
10
6
  use temporal_sdk_core_protos::{
11
7
  coresdk::workflow_commands::QueryResult,
12
8
  temporal::api::{
13
- common::v1::Payloads, enums::v1::WorkflowTaskFailedCause, failure::v1::Failure,
9
+ common::v1::{Payloads, WorkflowExecution},
10
+ enums::v1::{TaskQueueKind, WorkflowTaskFailedCause},
11
+ failure::v1::Failure,
12
+ query::v1::WorkflowQueryResult,
13
+ taskqueue::v1::{TaskQueue, TaskQueueMetadata},
14
14
  workflowservice::v1::*,
15
15
  },
16
16
  TaskToken,
17
17
  };
18
- use tonic::Code;
19
18
 
20
19
  type Result<T, E = tonic::Status> = std::result::Result<T, E>;
21
20
 
22
- /// Returns true if the network error should not be reported to lang. This can happen if we've
23
- /// exceeded the max number of retries, and we prefer to just warn rather than blowing up lang.
24
- pub(crate) fn should_swallow_net_error(err: &tonic::Status) -> bool {
25
- RETRYABLE_ERROR_CODES.contains(&err.code())
26
- || matches!(err.code(), Code::Cancelled | Code::DeadlineExceeded)
27
- }
28
-
29
21
  /// Contains everything a worker needs to interact with the server
30
22
  pub(crate) struct WorkerClientBag {
31
- client: Box<dyn WorkerClient>,
23
+ client: RetryClient<Client>,
32
24
  namespace: String,
25
+ identity: String,
26
+ worker_build_id: String,
27
+ use_versioning: bool,
33
28
  }
34
29
 
35
30
  impl WorkerClientBag {
36
- pub fn new(client: Box<dyn WorkerClient>, namespace: String) -> Self {
37
- Self { client, namespace }
31
+ pub fn new(
32
+ client: RetryClient<Client>,
33
+ namespace: String,
34
+ identity: String,
35
+ worker_build_id: String,
36
+ use_versioning: bool,
37
+ ) -> Self {
38
+ Self {
39
+ client,
40
+ namespace,
41
+ identity,
42
+ worker_build_id,
43
+ use_versioning,
44
+ }
38
45
  }
39
-
40
- pub fn namespace(&self) -> &str {
41
- &self.namespace
42
- }
43
- }
44
- impl Deref for WorkerClientBag {
45
- type Target = dyn WorkerClient;
46
-
47
- fn deref(&self) -> &Self::Target {
48
- &*self.client
49
- }
50
- }
51
- impl DerefMut for WorkerClientBag {
52
- fn deref_mut(&mut self) -> &mut Self::Target {
53
- &mut *self.client
54
- }
55
- }
56
- #[cfg(test)]
57
- impl<T> From<T> for WorkerClientBag
58
- where
59
- T: WorkerClient + 'static,
60
- {
61
- fn from(c: T) -> Self {
62
- use temporal_sdk_core_test_utils::NAMESPACE;
63
-
64
- WorkerClientBag::new(Box::new(c), NAMESPACE.to_string())
46
+ fn versioning_build_id(&self) -> String {
47
+ if self.use_versioning {
48
+ self.worker_build_id.clone()
49
+ } else {
50
+ "".to_string()
51
+ }
65
52
  }
66
53
  }
67
54
 
@@ -124,17 +111,37 @@ pub(crate) trait WorkerClient: Sync + Send {
124
111
  }
125
112
 
126
113
  #[async_trait::async_trait]
127
- impl<'a, T> WorkerClient for T
128
- where
129
- // TODO: This should be workflow service... no reason to marry worker trait to sdk client trait
130
- T: Borrow<dyn WorkflowClientTrait + 'a + Send + Sync> + Send + Sync,
131
- {
114
+ impl WorkerClient for WorkerClientBag {
132
115
  async fn poll_workflow_task(
133
116
  &self,
134
117
  task_queue: String,
135
118
  is_sticky: bool,
136
119
  ) -> Result<PollWorkflowTaskQueueResponse> {
137
- WorkflowClientTrait::poll_workflow_task(self.borrow(), task_queue, is_sticky).await
120
+ let request = PollWorkflowTaskQueueRequest {
121
+ namespace: self.namespace.clone(),
122
+ task_queue: Some(TaskQueue {
123
+ name: task_queue,
124
+ kind: if is_sticky {
125
+ TaskQueueKind::Sticky
126
+ } else {
127
+ TaskQueueKind::Normal
128
+ } as i32,
129
+ }),
130
+ identity: self.identity.clone(),
131
+ binary_checksum: if self.use_versioning {
132
+ "".to_string()
133
+ } else {
134
+ self.worker_build_id.clone()
135
+ },
136
+ worker_versioning_build_id: self.versioning_build_id(),
137
+ };
138
+
139
+ Ok(self
140
+ .client
141
+ .clone()
142
+ .poll_workflow_task_queue(request)
143
+ .await?
144
+ .into_inner())
138
145
  }
139
146
 
140
147
  async fn poll_activity_task(
@@ -142,14 +149,62 @@ where
142
149
  task_queue: String,
143
150
  max_tasks_per_sec: Option<f64>,
144
151
  ) -> Result<PollActivityTaskQueueResponse> {
145
- WorkflowClientTrait::poll_activity_task(self.borrow(), task_queue, max_tasks_per_sec).await
152
+ let request = PollActivityTaskQueueRequest {
153
+ namespace: self.namespace.clone(),
154
+ task_queue: Some(TaskQueue {
155
+ name: task_queue,
156
+ kind: TaskQueueKind::Normal as i32,
157
+ }),
158
+ identity: self.identity.clone(),
159
+ task_queue_metadata: max_tasks_per_sec.map(|tps| TaskQueueMetadata {
160
+ max_tasks_per_second: Some(tps),
161
+ }),
162
+ worker_versioning_build_id: self.versioning_build_id(),
163
+ };
164
+
165
+ Ok(self
166
+ .client
167
+ .clone()
168
+ .poll_activity_task_queue(request)
169
+ .await?
170
+ .into_inner())
146
171
  }
147
172
 
148
173
  async fn complete_workflow_task(
149
174
  &self,
150
175
  request: WorkflowTaskCompletion,
151
176
  ) -> Result<RespondWorkflowTaskCompletedResponse> {
152
- WorkflowClientTrait::complete_workflow_task(self.borrow(), request).await
177
+ let request = RespondWorkflowTaskCompletedRequest {
178
+ task_token: request.task_token.into(),
179
+ commands: request.commands,
180
+ identity: self.identity.clone(),
181
+ sticky_attributes: request.sticky_attributes,
182
+ return_new_workflow_task: request.return_new_workflow_task,
183
+ force_create_new_workflow_task: request.force_create_new_workflow_task,
184
+ binary_checksum: self.worker_build_id.clone(),
185
+ query_results: request
186
+ .query_responses
187
+ .into_iter()
188
+ .map(|qr| {
189
+ let (id, completed_type, query_result, error_message) = qr.into_components();
190
+ (
191
+ id,
192
+ WorkflowQueryResult {
193
+ result_type: completed_type as i32,
194
+ answer: query_result,
195
+ error_message,
196
+ },
197
+ )
198
+ })
199
+ .collect(),
200
+ namespace: self.namespace.clone(),
201
+ };
202
+ Ok(self
203
+ .client
204
+ .clone()
205
+ .respond_workflow_task_completed(request)
206
+ .await?
207
+ .into_inner())
153
208
  }
154
209
 
155
210
  async fn complete_activity_task(
@@ -157,7 +212,17 @@ where
157
212
  task_token: TaskToken,
158
213
  result: Option<Payloads>,
159
214
  ) -> Result<RespondActivityTaskCompletedResponse> {
160
- WorkflowClientTrait::complete_activity_task(self.borrow(), task_token, result).await
215
+ Ok(self
216
+ .client
217
+ .clone()
218
+ .respond_activity_task_completed(RespondActivityTaskCompletedRequest {
219
+ task_token: task_token.0,
220
+ result,
221
+ identity: self.identity.clone(),
222
+ namespace: self.namespace.clone(),
223
+ })
224
+ .await?
225
+ .into_inner())
161
226
  }
162
227
 
163
228
  async fn record_activity_heartbeat(
@@ -165,7 +230,17 @@ where
165
230
  task_token: TaskToken,
166
231
  details: Option<Payloads>,
167
232
  ) -> Result<RecordActivityTaskHeartbeatResponse> {
168
- WorkflowClientTrait::record_activity_heartbeat(self.borrow(), task_token, details).await
233
+ Ok(self
234
+ .client
235
+ .clone()
236
+ .record_activity_task_heartbeat(RecordActivityTaskHeartbeatRequest {
237
+ task_token: task_token.0,
238
+ details,
239
+ identity: self.identity.clone(),
240
+ namespace: self.namespace.clone(),
241
+ })
242
+ .await?
243
+ .into_inner())
169
244
  }
170
245
 
171
246
  async fn cancel_activity_task(
@@ -173,7 +248,17 @@ where
173
248
  task_token: TaskToken,
174
249
  details: Option<Payloads>,
175
250
  ) -> Result<RespondActivityTaskCanceledResponse> {
176
- WorkflowClientTrait::cancel_activity_task(self.borrow(), task_token, details).await
251
+ Ok(self
252
+ .client
253
+ .clone()
254
+ .respond_activity_task_canceled(RespondActivityTaskCanceledRequest {
255
+ task_token: task_token.0,
256
+ details,
257
+ identity: self.identity.clone(),
258
+ namespace: self.namespace.clone(),
259
+ })
260
+ .await?
261
+ .into_inner())
177
262
  }
178
263
 
179
264
  async fn fail_activity_task(
@@ -181,7 +266,19 @@ where
181
266
  task_token: TaskToken,
182
267
  failure: Option<Failure>,
183
268
  ) -> Result<RespondActivityTaskFailedResponse> {
184
- WorkflowClientTrait::fail_activity_task(self.borrow(), task_token, failure).await
269
+ Ok(self
270
+ .client
271
+ .clone()
272
+ .respond_activity_task_failed(RespondActivityTaskFailedRequest {
273
+ task_token: task_token.0,
274
+ failure,
275
+ identity: self.identity.clone(),
276
+ namespace: self.namespace.clone(),
277
+ // TODO: Implement - https://github.com/temporalio/sdk-core/issues/293
278
+ last_heartbeat_details: None,
279
+ })
280
+ .await?
281
+ .into_inner())
185
282
  }
186
283
 
187
284
  async fn fail_workflow_task(
@@ -190,7 +287,20 @@ where
190
287
  cause: WorkflowTaskFailedCause,
191
288
  failure: Option<Failure>,
192
289
  ) -> Result<RespondWorkflowTaskFailedResponse> {
193
- WorkflowClientTrait::fail_workflow_task(self.borrow(), task_token, cause, failure).await
290
+ let request = RespondWorkflowTaskFailedRequest {
291
+ task_token: task_token.0,
292
+ cause: cause as i32,
293
+ failure,
294
+ identity: self.identity.clone(),
295
+ binary_checksum: self.worker_build_id.clone(),
296
+ namespace: self.namespace.clone(),
297
+ };
298
+ Ok(self
299
+ .client
300
+ .clone()
301
+ .respond_workflow_task_failed(request)
302
+ .await?
303
+ .into_inner())
194
304
  }
195
305
 
196
306
  async fn get_workflow_execution_history(
@@ -199,13 +309,20 @@ where
199
309
  run_id: Option<String>,
200
310
  page_token: Vec<u8>,
201
311
  ) -> Result<GetWorkflowExecutionHistoryResponse> {
202
- WorkflowClientTrait::get_workflow_execution_history(
203
- self.borrow(),
204
- workflow_id,
205
- run_id,
206
- page_token,
207
- )
208
- .await
312
+ Ok(self
313
+ .client
314
+ .clone()
315
+ .get_workflow_execution_history(GetWorkflowExecutionHistoryRequest {
316
+ namespace: self.namespace.clone(),
317
+ execution: Some(WorkflowExecution {
318
+ workflow_id,
319
+ run_id: run_id.unwrap_or_default(),
320
+ }),
321
+ next_page_token: page_token,
322
+ ..Default::default()
323
+ })
324
+ .await?
325
+ .into_inner())
209
326
  }
210
327
 
211
328
  async fn respond_legacy_query(
@@ -213,6 +330,18 @@ where
213
330
  task_token: TaskToken,
214
331
  query_result: QueryResult,
215
332
  ) -> Result<RespondQueryTaskCompletedResponse> {
216
- WorkflowClientTrait::respond_legacy_query(self.borrow(), task_token, query_result).await
333
+ let (_, completed_type, query_result, error_message) = query_result.into_components();
334
+ Ok(self
335
+ .client
336
+ .clone()
337
+ .respond_query_task_completed(RespondQueryTaskCompletedRequest {
338
+ task_token: task_token.into(),
339
+ completed_type: completed_type as i32,
340
+ query_result,
341
+ error_message,
342
+ namespace: self.namespace.clone(),
343
+ })
344
+ .await?
345
+ .into_inner())
217
346
  }
218
347
  }