@temporalio/core-bridge 1.4.4 → 1.5.1

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 (123) hide show
  1. package/Cargo.lock +327 -419
  2. package/Cargo.toml +1 -1
  3. package/index.js +25 -2
  4. package/lib/errors.d.ts +22 -0
  5. package/lib/errors.js +65 -0
  6. package/lib/errors.js.map +1 -0
  7. package/lib/index.d.ts +440 -0
  8. package/lib/index.js +8 -0
  9. package/lib/index.js.map +1 -0
  10. package/package.json +11 -5
  11. package/releases/aarch64-apple-darwin/index.node +0 -0
  12. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  13. package/releases/x86_64-apple-darwin/index.node +0 -0
  14. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  15. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  16. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  17. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  18. package/sdk-core/bridge-ffi/Cargo.toml +1 -1
  19. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -25
  20. package/sdk-core/bridge-ffi/src/lib.rs +29 -108
  21. package/sdk-core/bridge-ffi/src/wrappers.rs +35 -25
  22. package/sdk-core/client/Cargo.toml +1 -1
  23. package/sdk-core/client/src/lib.rs +12 -20
  24. package/sdk-core/client/src/raw.rs +9 -8
  25. package/sdk-core/client/src/retry.rs +100 -23
  26. package/sdk-core/core/Cargo.toml +5 -5
  27. package/sdk-core/core/benches/workflow_replay.rs +13 -10
  28. package/sdk-core/core/src/abstractions.rs +22 -22
  29. package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
  30. package/sdk-core/core/src/core_tests/local_activities.rs +228 -6
  31. package/sdk-core/core/src/core_tests/queries.rs +247 -89
  32. package/sdk-core/core/src/core_tests/workers.rs +2 -2
  33. package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  34. package/sdk-core/core/src/core_tests/workflow_tasks.rs +46 -27
  35. package/sdk-core/core/src/lib.rs +139 -32
  36. package/sdk-core/core/src/replay/mod.rs +185 -41
  37. package/sdk-core/core/src/telemetry/log_export.rs +190 -0
  38. package/sdk-core/core/src/telemetry/metrics.rs +184 -139
  39. package/sdk-core/core/src/telemetry/mod.rs +296 -318
  40. package/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
  41. package/sdk-core/core/src/test_help/mod.rs +9 -7
  42. package/sdk-core/core/src/worker/activities/local_activities.rs +2 -1
  43. package/sdk-core/core/src/worker/activities.rs +40 -23
  44. package/sdk-core/core/src/worker/client/mocks.rs +1 -1
  45. package/sdk-core/core/src/worker/client.rs +30 -4
  46. package/sdk-core/core/src/worker/mod.rs +22 -18
  47. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
  48. package/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
  49. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
  50. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
  51. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
  52. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -5
  53. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
  54. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
  55. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
  56. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +18 -21
  57. package/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
  58. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
  59. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
  60. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
  61. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
  62. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
  63. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
  64. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +232 -216
  65. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
  66. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
  67. package/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
  68. package/sdk-core/core/src/worker/workflow/mod.rs +61 -9
  69. package/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
  70. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
  71. package/sdk-core/core-api/Cargo.toml +4 -3
  72. package/sdk-core/core-api/src/lib.rs +1 -43
  73. package/sdk-core/core-api/src/telemetry.rs +147 -0
  74. package/sdk-core/core-api/src/worker.rs +13 -0
  75. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  76. package/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  77. package/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  78. package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
  79. package/sdk-core/protos/api_upstream/buf.yaml +0 -3
  80. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +3 -7
  81. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +8 -0
  82. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -2
  83. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +2 -0
  84. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
  85. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -0
  86. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +19 -59
  87. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -19
  88. package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +108 -29
  89. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
  90. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
  91. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +47 -8
  92. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +15 -1
  93. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  94. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
  95. package/sdk-core/sdk/src/interceptors.rs +36 -3
  96. package/sdk-core/sdk/src/lib.rs +7 -4
  97. package/sdk-core/sdk/src/workflow_context.rs +13 -2
  98. package/sdk-core/sdk-core-protos/src/history_builder.rs +47 -1
  99. package/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
  100. package/sdk-core/sdk-core-protos/src/lib.rs +49 -27
  101. package/sdk-core/test-utils/Cargo.toml +1 -0
  102. package/sdk-core/test-utils/src/lib.rs +81 -29
  103. package/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
  104. package/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
  105. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +145 -4
  106. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
  107. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
  108. package/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
  109. package/sdk-core/tests/main.rs +6 -4
  110. package/src/conversions.rs +52 -47
  111. package/src/errors.rs +28 -86
  112. package/src/helpers.rs +3 -4
  113. package/src/lib.rs +2 -2
  114. package/src/runtime.rs +132 -61
  115. package/src/testing.rs +7 -4
  116. package/src/worker.rs +67 -50
  117. package/ts/errors.ts +55 -0
  118. package/{index.d.ts → ts/index.ts} +121 -15
  119. package/sdk-core/core/src/log_export.rs +0 -62
  120. package/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
  121. package/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
  122. package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
  123. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +0 -40
@@ -1,4 +1,4 @@
1
- use crate::telemetry::{default_resource, metrics::SDKAggSelector};
1
+ use crate::telemetry::default_resource;
2
2
  use hyper::{
3
3
  header::CONTENT_TYPE,
4
4
  service::{make_service_fn, service_fn},
@@ -7,7 +7,7 @@ use hyper::{
7
7
  use opentelemetry::{
8
8
  metrics::MetricsError,
9
9
  sdk::{
10
- export::metrics::aggregation::TemporalitySelector,
10
+ export::metrics::{aggregation::TemporalitySelector, AggregatorSelector},
11
11
  metrics::{controllers, processors},
12
12
  },
13
13
  };
@@ -24,10 +24,11 @@ pub(super) struct PromServer {
24
24
  impl PromServer {
25
25
  pub fn new(
26
26
  addr: SocketAddr,
27
+ aggregation: impl AggregatorSelector + Send + Sync + 'static,
27
28
  temporality: impl TemporalitySelector + Send + Sync + 'static,
28
29
  ) -> Result<Self, MetricsError> {
29
30
  let controller =
30
- controllers::basic(processors::factory(SDKAggSelector, temporality).with_memory(true))
31
+ controllers::basic(processors::factory(aggregation, temporality).with_memory(true))
31
32
  .with_resource(default_resource())
32
33
  .build();
33
34
  let exporter = ExporterBuilder::new(controller).try_init()?;
@@ -5,8 +5,11 @@ use crate::{
5
5
  protosext::ValidPollWFTQResponse,
6
6
  replay::TestHistoryBuilder,
7
7
  sticky_q_name_for_worker,
8
+ telemetry::metrics::MetricsContext,
8
9
  worker::{
9
- client::{mocks::mock_workflow_client, MockWorkerClient, WorkerClient},
10
+ client::{
11
+ mocks::mock_workflow_client, MockWorkerClient, WorkerClient, WorkflowTaskCompletion,
12
+ },
10
13
  new_wft_poller,
11
14
  },
12
15
  TaskToken, Worker, WorkerConfig, WorkerConfigBuilder,
@@ -26,7 +29,6 @@ use std::{
26
29
  task::{Context, Poll},
27
30
  time::Duration,
28
31
  };
29
- use temporal_client::WorkflowTaskCompletion;
30
32
  use temporal_sdk_core_api::Worker as WorkerTrait;
31
33
  use temporal_sdk_core_protos::{
32
34
  coresdk::{
@@ -57,6 +59,7 @@ pub fn test_worker_cfg() -> WorkerConfigBuilder {
57
59
  wcb.namespace("default")
58
60
  .task_queue(TEST_Q)
59
61
  .worker_build_id("test_bin_id")
62
+ .ignore_evicts_on_shutdown(true)
60
63
  // Serial polling since it makes mocking much easier.
61
64
  .max_concurrent_wft_polls(1_usize);
62
65
  wcb
@@ -144,7 +147,7 @@ pub(crate) fn mock_worker(mocks: MocksHolder) -> Worker {
144
147
  mocks.client,
145
148
  mocks.inputs.wft_stream,
146
149
  act_poller,
147
- Default::default(),
150
+ MetricsContext::no_op(),
148
151
  CancellationToken::new(),
149
152
  )
150
153
  }
@@ -214,7 +217,7 @@ impl MockWorkerInputs {
214
217
  }
215
218
  pub fn new_from_poller(wf_poller: BoxedWFPoller) -> Self {
216
219
  Self {
217
- wft_stream: new_wft_poller(wf_poller, Default::default()).boxed(),
220
+ wft_stream: new_wft_poller(wf_poller, MetricsContext::no_op()).boxed(),
218
221
  act_poller: None,
219
222
  config: test_worker_cfg().build().unwrap(),
220
223
  }
@@ -503,7 +506,7 @@ pub(crate) fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder {
503
506
  .into_iter()
504
507
  .map(|response| {
505
508
  let cur_attempt = attempts_at_task_num.entry(response.hashable()).or_insert(1);
506
- let mut r = hist_to_poll_resp(&hist.hist, hist.wf_id.clone(), response, TEST_Q);
509
+ let mut r = hist_to_poll_resp(&hist.hist, hist.wf_id.clone(), response);
507
510
  r.attempt = *cur_attempt;
508
511
  *cur_attempt += 1;
509
512
  r
@@ -654,7 +657,6 @@ pub fn hist_to_poll_resp(
654
657
  t: &TestHistoryBuilder,
655
658
  wf_id: impl Into<String>,
656
659
  response_type: ResponseType,
657
- task_queue: impl Into<String>,
658
660
  ) -> QueueResponse<PollWorkflowTaskQueueResponse> {
659
661
  let run_id = t.get_orig_run_id();
660
662
  let wf = WorkflowExecution {
@@ -683,7 +685,7 @@ pub fn hist_to_poll_resp(
683
685
  }
684
686
  }
685
687
  };
686
- let mut resp = hist_info.as_poll_wft_response(task_queue);
688
+ let mut resp = hist_info.as_poll_wft_response();
687
689
  resp.workflow_execution = Some(wf);
688
690
  QueueResponse { resp, delay_until }
689
691
  }
@@ -179,7 +179,7 @@ impl LocalActivityManager {
179
179
  Self::new(
180
180
  max_concurrent,
181
181
  "fake_ns".to_string(),
182
- MetricsContext::default(),
182
+ MetricsContext::no_op(),
183
183
  )
184
184
  }
185
185
 
@@ -515,6 +515,7 @@ enum CancelOrTimeout {
515
515
  },
516
516
  }
517
517
 
518
+ #[allow(clippy::large_enum_variant)]
518
519
  enum NewOrCancel {
519
520
  New(NewOrRetry, OwnedMeteredSemPermit),
520
521
  Cancel(CancelOrTimeout),
@@ -7,6 +7,7 @@ pub(crate) use local_activities::{
7
7
  LocalInFlightActInfo, NewLocalAct,
8
8
  };
9
9
 
10
+ use crate::telemetry::metrics::eager;
10
11
  use crate::{
11
12
  abstractions::{MeteredSemaphore, OwnedMeteredSemPermit},
12
13
  pollers::BoxedActPoller,
@@ -41,6 +42,7 @@ use temporal_sdk_core_protos::{
41
42
  },
42
43
  };
43
44
  use tokio::sync::Notify;
45
+ use tracing::Span;
44
46
 
45
47
  #[derive(Debug, derive_more::Constructor)]
46
48
  struct PendingActivityCancel {
@@ -48,11 +50,15 @@ struct PendingActivityCancel {
48
50
  reason: ActivityCancelReason,
49
51
  }
50
52
 
51
- /// Contains minimal set of details that core needs to store while an activity is running.
53
+ /// Contains details that core wants to store while an activity is running.
52
54
  #[derive(Debug)]
53
55
  struct InFlightActInfo {
54
56
  pub activity_type: String,
55
57
  pub workflow_type: String,
58
+ /// Only kept for logging reasons
59
+ pub workflow_id: String,
60
+ /// Only kept for logging reasons
61
+ pub workflow_run_id: String,
56
62
  start_time: Instant,
57
63
  }
58
64
 
@@ -71,19 +77,17 @@ struct RemoteInFlightActInfo {
71
77
  _permit: OwnedMeteredSemPermit,
72
78
  }
73
79
  impl RemoteInFlightActInfo {
74
- fn new(
75
- activity_type: String,
76
- workflow_type: String,
77
- heartbeat_timeout: Option<prost_types::Duration>,
78
- permit: OwnedMeteredSemPermit,
79
- ) -> Self {
80
+ fn new(poll_resp: &PollActivityTaskQueueResponse, permit: OwnedMeteredSemPermit) -> Self {
81
+ let wec = poll_resp.workflow_execution.clone().unwrap_or_default();
80
82
  Self {
81
83
  base: InFlightActInfo {
82
- activity_type,
83
- workflow_type,
84
+ activity_type: poll_resp.activity_type.clone().unwrap_or_default().name,
85
+ workflow_type: poll_resp.workflow_type.clone().unwrap_or_default().name,
86
+ workflow_id: wec.workflow_id,
87
+ workflow_run_id: wec.run_id,
84
88
  start_time: Instant::now(),
85
89
  },
86
- heartbeat_timeout,
90
+ heartbeat_timeout: poll_resp.heartbeat_timeout.clone(),
87
91
  issued_cancel_to_lang: false,
88
92
  known_not_found: false,
89
93
  _permit: permit,
@@ -202,7 +206,7 @@ impl WorkerActivityTasks {
202
206
  cancel_task
203
207
  }
204
208
  task = self.non_poll_tasks.next() => {
205
- Ok(Some(self.about_to_issue_task(task)))
209
+ Ok(Some(self.about_to_issue_task(task, true)))
206
210
  }
207
211
  (work, permit) = poll_with_semaphore => {
208
212
  match work {
@@ -214,7 +218,7 @@ impl WorkerActivityTasks {
214
218
  }
215
219
  let work = self.about_to_issue_task(PermittedTqResp {
216
220
  resp: work, permit
217
- });
221
+ }, false);
218
222
  Ok(Some(work))
219
223
  }
220
224
  None => {
@@ -234,12 +238,14 @@ impl WorkerActivityTasks {
234
238
  ) {
235
239
  if let Some((_, act_info)) = self.outstanding_activity_tasks.remove(&task_token) {
236
240
  let act_metrics = self.metrics.with_new_attrs([
237
- activity_type(act_info.base.activity_type.clone()),
238
- workflow_type(act_info.base.workflow_type.clone()),
241
+ activity_type(act_info.base.activity_type),
242
+ workflow_type(act_info.base.workflow_type),
239
243
  ]);
244
+ Span::current().record("workflow_id", act_info.base.workflow_id);
245
+ Span::current().record("run_id", act_info.base.workflow_run_id);
240
246
  act_metrics.act_execution_latency(act_info.base.start_time.elapsed());
241
247
  let known_not_found = act_info.known_not_found;
242
- drop(act_info); // TODO: Get rid of dashmap. If we hold ref across await, bad stuff.
248
+
243
249
  self.heartbeat_manager.evict(task_token.clone()).await;
244
250
  self.complete_notify.notify_waiters();
245
251
 
@@ -369,19 +375,28 @@ impl WorkerActivityTasks {
369
375
  }
370
376
 
371
377
  /// Called when there is a new act task about to be bubbled up out of the manager
372
- fn about_to_issue_task(&self, task: PermittedTqResp) -> ActivityTask {
378
+ fn about_to_issue_task(&self, task: PermittedTqResp, is_eager: bool) -> ActivityTask {
379
+ if let Some(ref act_type) = task.resp.activity_type {
380
+ if let Some(ref wf_type) = task.resp.workflow_type {
381
+ self.metrics
382
+ .with_new_attrs([
383
+ activity_type(act_type.name.clone()),
384
+ workflow_type(wf_type.name.clone()),
385
+ eager(is_eager),
386
+ ])
387
+ .act_task_received();
388
+ }
389
+ }
390
+ // There could be an else statement here but since the response should always contain both
391
+ // activity_type and workflow_type, we won't bother.
392
+
373
393
  if let Some(dur) = task.resp.sched_to_start() {
374
394
  self.metrics.act_sched_to_start_latency(dur);
375
395
  };
376
396
 
377
397
  self.outstanding_activity_tasks.insert(
378
398
  task.resp.task_token.clone().into(),
379
- RemoteInFlightActInfo::new(
380
- task.resp.activity_type.clone().unwrap_or_default().name,
381
- task.resp.workflow_type.clone().unwrap_or_default().name,
382
- task.resp.heartbeat_timeout.clone(),
383
- task.permit,
384
- ),
399
+ RemoteInFlightActInfo::new(&task.resp, task.permit),
385
400
  );
386
401
 
387
402
  ActivityTask::start_from_poll_resp(task.resp)
@@ -411,6 +426,8 @@ impl ActivitiesFromWFTsHandle {
411
426
  /// from WFT completion)
412
427
  pub(crate) fn add_tasks(&self, tasks: impl IntoIterator<Item = PermittedTqResp>) {
413
428
  for t in tasks.into_iter() {
429
+ // Technically we should be reporting `activity_task_received` here, but for simplicity
430
+ // and time insensitivity, that metric is tracked in `about_to_issue_task`.
414
431
  self.tx.try_send(t).expect("Receive half cannot be dropped");
415
432
  }
416
433
  }
@@ -449,7 +466,7 @@ mod tests {
449
466
  Some(2.0),
450
467
  poller,
451
468
  Arc::new(mock_manual_workflow_client()),
452
- MetricsContext::default(),
469
+ MetricsContext::no_op(),
453
470
  Duration::from_secs(1),
454
471
  Duration::from_secs(1),
455
472
  );
@@ -16,7 +16,7 @@ pub(crate) fn mock_manual_workflow_client() -> MockManualWorkerClient {
16
16
  // results. This is really annoying b/c of the async trait stuff. Need
17
17
  // https://github.com/asomers/mockall/issues/189 to be fixed for it to go away.
18
18
  mockall::mock! {
19
- pub ManualWorkerClient {}
19
+ pub(crate) ManualWorkerClient {}
20
20
  #[allow(unused)]
21
21
  impl WorkerClient for ManualWorkerClient {
22
22
  fn poll_workflow_task<'a, 'b>(&'a self, task_queue: String, is_sticky: bool)
@@ -2,15 +2,16 @@
2
2
 
3
3
  pub(crate) mod mocks;
4
4
 
5
- use temporal_client::{Client, RetryClient, WorkflowService, WorkflowTaskCompletion};
5
+ use temporal_client::{Client, RetryClient, WorkflowService};
6
6
  use temporal_sdk_core_protos::{
7
7
  coresdk::workflow_commands::QueryResult,
8
8
  temporal::api::{
9
+ command::v1::Command,
9
10
  common::v1::{Payloads, WorkflowExecution},
10
11
  enums::v1::{TaskQueueKind, WorkflowTaskFailedCause},
11
12
  failure::v1::Failure,
12
13
  query::v1::WorkflowQueryResult,
13
- taskqueue::v1::{TaskQueue, TaskQueueMetadata},
14
+ taskqueue::v1::{StickyExecutionAttributes, TaskQueue, TaskQueueMetadata, VersionId},
14
15
  workflowservice::v1::*,
15
16
  },
16
17
  TaskToken,
@@ -133,7 +134,9 @@ impl WorkerClient for WorkerClientBag {
133
134
  } else {
134
135
  self.worker_build_id.clone()
135
136
  },
136
- worker_versioning_build_id: self.versioning_build_id(),
137
+ worker_versioning_id: Some(VersionId {
138
+ worker_build_id: self.versioning_build_id(),
139
+ }),
137
140
  };
138
141
 
139
142
  Ok(self
@@ -159,7 +162,9 @@ impl WorkerClient for WorkerClientBag {
159
162
  task_queue_metadata: max_tasks_per_sec.map(|tps| TaskQueueMetadata {
160
163
  max_tasks_per_second: Some(tps),
161
164
  }),
162
- worker_versioning_build_id: self.versioning_build_id(),
165
+ worker_versioning_id: Some(VersionId {
166
+ worker_build_id: self.versioning_build_id(),
167
+ }),
163
168
  };
164
169
 
165
170
  Ok(self
@@ -181,6 +186,9 @@ impl WorkerClient for WorkerClientBag {
181
186
  sticky_attributes: request.sticky_attributes,
182
187
  return_new_workflow_task: request.return_new_workflow_task,
183
188
  force_create_new_workflow_task: request.force_create_new_workflow_task,
189
+ worker_versioning_id: Some(VersionId {
190
+ worker_build_id: self.versioning_build_id(),
191
+ }),
184
192
  binary_checksum: self.worker_build_id.clone(),
185
193
  query_results: request
186
194
  .query_responses
@@ -345,3 +353,21 @@ impl WorkerClient for WorkerClientBag {
345
353
  .into_inner())
346
354
  }
347
355
  }
356
+
357
+ /// A version of [RespondWorkflowTaskCompletedRequest] that will finish being filled out by the
358
+ /// server client
359
+ #[derive(Debug, Clone, PartialEq)]
360
+ pub(crate) struct WorkflowTaskCompletion {
361
+ /// The task token that would've been received from polling for a workflow activation
362
+ pub task_token: TaskToken,
363
+ /// A list of new commands to send to the server, such as starting a timer.
364
+ pub commands: Vec<Command>,
365
+ /// If set, indicate that next task should be queued on sticky queue with given attributes.
366
+ pub sticky_attributes: Option<StickyExecutionAttributes>,
367
+ /// Responses to queries in the `queries` field of the workflow task.
368
+ pub query_responses: Vec<QueryResult>,
369
+ /// Indicate that the task completion should return a new WFT if one is available
370
+ pub return_new_workflow_task: bool,
371
+ /// Force a new WFT to be created after this completion
372
+ pub force_create_new_workflow_task: bool,
373
+ }
@@ -74,7 +74,7 @@ impl WorkerTrait for Worker {
74
74
  self.next_workflow_activation().await
75
75
  }
76
76
 
77
- #[instrument(level = "debug", skip(self))]
77
+ #[instrument(skip(self))]
78
78
  async fn poll_activity_task(&self) -> Result<ActivityTask, PollActivityError> {
79
79
  loop {
80
80
  match self.activity_poll().await.transpose() {
@@ -94,7 +94,6 @@ impl WorkerTrait for Worker {
94
94
  self.complete_workflow_activation(completion).await
95
95
  }
96
96
 
97
- #[instrument(level = "debug", skip(self, completion), fields(completion=%&completion))]
98
97
  async fn complete_activity_task(
99
98
  &self,
100
99
  completion: ActivityTaskCompletion,
@@ -135,7 +134,11 @@ impl WorkerTrait for Worker {
135
134
  if let Some(atm) = self.at_task_mgr.as_ref() {
136
135
  atm.notify_shutdown();
137
136
  }
138
- info!("Initiated shutdown");
137
+ info!(
138
+ task_queue=%self.config.task_queue,
139
+ namespace=%self.config.namespace,
140
+ "Initiated shutdown",
141
+ );
139
142
  }
140
143
 
141
144
  async fn shutdown(&self) {
@@ -155,7 +158,9 @@ impl Worker {
155
158
  client: Arc<dyn WorkerClient>,
156
159
  metrics: MetricsContext,
157
160
  ) -> Self {
158
- info!(task_queue = %config.task_queue, "Initializing worker");
161
+ info!(task_queue=%config.task_queue,
162
+ namespace=%config.namespace,
163
+ "Initializing worker");
159
164
  metrics.worker_registered();
160
165
 
161
166
  let shutdown_token = CancellationToken::new();
@@ -224,7 +229,7 @@ impl Worker {
224
229
 
225
230
  #[cfg(test)]
226
231
  pub(crate) fn new_test(config: WorkerConfig, client: impl WorkerClient + 'static) -> Self {
227
- Self::new(config, None, Arc::new(client), Default::default())
232
+ Self::new(config, None, Arc::new(client), MetricsContext::no_op())
228
233
  }
229
234
 
230
235
  pub(crate) fn new_with_pollers(
@@ -264,6 +269,7 @@ impl Worker {
264
269
  metrics,
265
270
  namespace: config.namespace.clone(),
266
271
  task_queue: config.task_queue.clone(),
272
+ ignore_evicts_on_shutdown: config.ignore_evicts_on_shutdown,
267
273
  },
268
274
  sticky_queue_name.map(|sq| StickyExecutionAttributes {
269
275
  worker_task_queue: Some(TaskQueue {
@@ -317,6 +323,10 @@ impl Worker {
317
323
  }
318
324
  }
319
325
 
326
+ pub(crate) fn shutdown_token(&self) -> CancellationToken {
327
+ self.shutdown_token.clone()
328
+ }
329
+
320
330
  /// Returns number of currently cached workflows
321
331
  pub async fn cached_workflows(&self) -> usize {
322
332
  self.workflows
@@ -394,6 +404,9 @@ impl Worker {
394
404
  }
395
405
  }
396
406
 
407
+ #[instrument(skip(self, task_token, status),
408
+ fields(task_token=%&task_token, status=%&status,
409
+ task_queue=%self.config.task_queue, workflow_id, run_id))]
397
410
  pub(crate) async fn complete_activity(
398
411
  &self,
399
412
  task_token: TaskToken,
@@ -433,13 +446,14 @@ impl Worker {
433
446
  Ok(())
434
447
  }
435
448
 
436
- #[instrument(level = "debug", skip(self), fields(run_id))]
449
+ #[instrument(skip(self), fields(run_id, workflow_id, task_queue=%self.config.task_queue))]
437
450
  pub(crate) async fn next_workflow_activation(&self) -> Result<WorkflowActivation, PollWfError> {
438
451
  self.workflows.next_workflow_activation().await
439
452
  }
440
453
 
441
- #[instrument(level = "debug", skip(self, completion),
442
- fields(completion=%&completion, run_id=%completion.run_id))]
454
+ #[instrument(skip(self, completion),
455
+ fields(completion=%&completion, run_id=%completion.run_id, workflow_id,
456
+ task_queue=%self.config.task_queue))]
443
457
  pub(crate) async fn complete_workflow_activation(
444
458
  &self,
445
459
  completion: WorkflowActivationCompletion,
@@ -470,16 +484,6 @@ impl Worker {
470
484
  self.post_activate_hook = Some(Box::new(callback))
471
485
  }
472
486
 
473
- /// Used for replay workers - causes the worker to shutdown when the given run reaches the
474
- /// given event number
475
- pub(crate) fn set_shutdown_on_run_reaches_event(&mut self, run_id: String, last_event: i64) {
476
- self.set_post_activate_hook(move |worker, activated_run_id, last_processed_event| {
477
- if activated_run_id == run_id && last_processed_event >= last_event as usize {
478
- worker.initiate_shutdown();
479
- }
480
- });
481
- }
482
-
483
487
  fn complete_local_act(
484
488
  &self,
485
489
  la_res: LocalActivityExecutionResult,
@@ -1,9 +1,7 @@
1
- use crate::worker::workflow::{WFCommand, WorkflowStartedInfo};
1
+ use crate::worker::workflow::{OutgoingJob, WFCommand, WorkflowStartedInfo};
2
+ use prost_types::Timestamp;
2
3
  use temporal_sdk_core_protos::{
3
- coresdk::workflow_activation::{
4
- start_workflow_from_attribs, workflow_activation_job, CancelWorkflow, SignalWorkflow,
5
- WorkflowActivationJob,
6
- },
4
+ coresdk::workflow_activation::{start_workflow_from_attribs, WorkflowActivationJob},
7
5
  temporal::api::history::v1::WorkflowExecutionStartedEventAttributes,
8
6
  utilities::TryIntoOrNone,
9
7
  };
@@ -14,7 +12,7 @@ pub struct DrivenWorkflow {
14
12
  started_attrs: Option<WorkflowStartedInfo>,
15
13
  fetcher: Box<dyn WorkflowFetcher>,
16
14
  /// Outgoing activation jobs that need to be sent to the lang sdk
17
- outgoing_wf_activation_jobs: Vec<workflow_activation_job::Variant>,
15
+ outgoing_wf_activation_jobs: Vec<OutgoingJob>,
18
16
  }
19
17
 
20
18
  impl<WF> From<Box<WF>> for DrivenWorkflow
@@ -36,6 +34,7 @@ impl DrivenWorkflow {
36
34
  &mut self,
37
35
  workflow_id: String,
38
36
  randomness_seed: u64,
37
+ start_time: Timestamp,
39
38
  attribs: WorkflowExecutionStartedEventAttributes,
40
39
  ) {
41
40
  debug!(run_id = %attribs.original_execution_run_id, "Driven WF start");
@@ -49,7 +48,9 @@ impl DrivenWorkflow {
49
48
  search_attrs: attribs.search_attributes.clone(),
50
49
  retry_policy: attribs.retry_policy.clone(),
51
50
  };
52
- self.send_job(start_workflow_from_attribs(attribs, workflow_id, randomness_seed).into());
51
+ self.send_job(
52
+ start_workflow_from_attribs(attribs, workflow_id, randomness_seed, start_time).into(),
53
+ );
53
54
  self.started_attrs = Some(started_info);
54
55
  }
55
56
 
@@ -59,12 +60,12 @@ impl DrivenWorkflow {
59
60
  }
60
61
 
61
62
  /// Enqueue a new job to be sent to the driven workflow
62
- pub fn send_job(&mut self, job: workflow_activation_job::Variant) {
63
+ pub(super) fn send_job(&mut self, job: OutgoingJob) {
63
64
  self.outgoing_wf_activation_jobs.push(job);
64
65
  }
65
66
 
66
67
  /// Observe pending jobs
67
- pub fn peek_pending_jobs(&self) -> &[workflow_activation_job::Variant] {
68
+ pub(super) fn peek_pending_jobs(&self) -> &[OutgoingJob] {
68
69
  self.outgoing_wf_activation_jobs.as_slice()
69
70
  }
70
71
 
@@ -75,16 +76,6 @@ impl DrivenWorkflow {
75
76
  .map(Into::into)
76
77
  .collect()
77
78
  }
78
-
79
- /// Signal the workflow
80
- pub fn signal(&mut self, signal: SignalWorkflow) {
81
- self.send_job(workflow_activation_job::Variant::SignalWorkflow(signal));
82
- }
83
-
84
- /// Cancel the workflow
85
- pub fn cancel(&mut self, attribs: CancelWorkflow) {
86
- self.send_job(workflow_activation_job::Variant::CancelWorkflow(attribs));
87
- }
88
79
  }
89
80
 
90
81
  #[async_trait::async_trait]