@temporalio/core-bridge 1.1.0 → 1.3.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 (114) hide show
  1. package/Cargo.lock +786 -54
  2. package/Cargo.toml +2 -2
  3. package/common.js +7 -3
  4. package/index.d.ts +110 -3
  5. package/index.js +2 -6
  6. package/package.json +3 -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/ARCHITECTURE.md +2 -2
  15. package/sdk-core/README.md +12 -0
  16. package/sdk-core/bridge-ffi/Cargo.toml +2 -2
  17. package/sdk-core/client/Cargo.toml +6 -4
  18. package/sdk-core/client/src/lib.rs +338 -215
  19. package/sdk-core/client/src/raw.rs +352 -106
  20. package/sdk-core/client/src/retry.rs +159 -133
  21. package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
  22. package/sdk-core/core/Cargo.toml +18 -9
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +63 -23
  24. package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
  25. package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
  26. package/sdk-core/core/src/core_tests/workers.rs +3 -2
  27. package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
  28. package/sdk-core/core/src/ephemeral_server/mod.rs +499 -0
  29. package/sdk-core/core/src/lib.rs +60 -26
  30. package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
  31. package/sdk-core/core/src/replay/mod.rs +3 -3
  32. package/sdk-core/core/src/retry_logic.rs +10 -9
  33. package/sdk-core/core/src/telemetry/mod.rs +10 -7
  34. package/sdk-core/core/src/test_help/mod.rs +18 -8
  35. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
  36. package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
  37. package/sdk-core/core/src/worker/activities.rs +6 -12
  38. package/sdk-core/core/src/worker/client.rs +193 -64
  39. package/sdk-core/core/src/worker/mod.rs +14 -19
  40. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
  41. package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
  42. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
  43. package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
  44. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
  45. package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
  46. package/sdk-core/core/src/worker/workflow/mod.rs +59 -58
  47. package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
  48. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
  49. package/sdk-core/core-api/Cargo.toml +2 -2
  50. package/sdk-core/core-api/src/errors.rs +3 -11
  51. package/sdk-core/core-api/src/worker.rs +7 -0
  52. package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
  53. package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
  54. package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
  55. package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
  56. package/sdk-core/protos/api_upstream/Makefile +2 -2
  57. package/sdk-core/protos/api_upstream/buf.yaml +1 -0
  58. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
  59. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
  60. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
  61. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
  62. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
  63. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
  64. package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
  65. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
  66. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
  67. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
  68. package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
  69. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
  70. package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
  71. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
  72. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
  73. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
  74. package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
  75. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
  76. package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
  77. package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
  78. package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
  79. package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
  80. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
  81. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
  82. package/sdk-core/sdk/Cargo.toml +2 -2
  83. package/sdk-core/sdk/src/lib.rs +2 -2
  84. package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
  85. package/sdk-core/sdk/src/workflow_context.rs +30 -6
  86. package/sdk-core/sdk/src/workflow_future.rs +4 -4
  87. package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
  88. package/sdk-core/sdk-core-protos/build.rs +9 -1
  89. package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
  90. package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
  91. package/sdk-core/test-utils/Cargo.toml +3 -3
  92. package/sdk-core/test-utils/src/canned_histories.rs +58 -0
  93. package/sdk-core/test-utils/src/lib.rs +14 -10
  94. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +141 -0
  95. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
  96. package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
  97. package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
  98. package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
  99. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
  100. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  101. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
  102. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +1 -1
  103. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
  104. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
  105. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
  106. package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
  107. package/sdk-core/tests/load_tests.rs +2 -1
  108. package/sdk-core/tests/main.rs +10 -0
  109. package/src/conversions.rs +138 -91
  110. package/src/helpers.rs +190 -0
  111. package/src/lib.rs +10 -912
  112. package/src/runtime.rs +436 -0
  113. package/src/testing.rs +67 -0
  114. package/src/worker.rs +465 -0
@@ -1,4 +1,6 @@
1
1
  use std::{collections::HashMap, time::Duration};
2
+
3
+ use temporal_client::WorkflowOptions;
2
4
  use temporal_sdk_core_protos::{
3
5
  coresdk::{
4
6
  child_workflow::ChildWorkflowCancellationType,
@@ -59,6 +61,8 @@ pub struct ActivityOptions {
59
61
  pub heartbeat_timeout: Option<Duration>,
60
62
  /// Determines what the SDK does when the Activity is cancelled.
61
63
  pub cancellation_type: ActivityCancellationType,
64
+ /// Activity retry policy
65
+ pub retry_policy: Option<RetryPolicy>,
62
66
  }
63
67
 
64
68
  impl IntoWorkflowCommand for ActivityOptions {
@@ -72,12 +76,17 @@ impl IntoWorkflowCommand for ActivityOptions {
72
76
  },
73
77
  activity_type: self.activity_type,
74
78
  task_queue: self.task_queue,
75
- schedule_to_close_timeout: self.schedule_to_close_timeout.map(Into::into),
76
- schedule_to_start_timeout: self.schedule_to_start_timeout.map(Into::into),
77
- start_to_close_timeout: self.start_to_close_timeout.map(Into::into),
78
- heartbeat_timeout: self.heartbeat_timeout.map(Into::into),
79
+ schedule_to_close_timeout: self
80
+ .schedule_to_close_timeout
81
+ .and_then(|d| d.try_into().ok()),
82
+ schedule_to_start_timeout: self
83
+ .schedule_to_start_timeout
84
+ .and_then(|d| d.try_into().ok()),
85
+ start_to_close_timeout: self.start_to_close_timeout.and_then(|d| d.try_into().ok()),
86
+ heartbeat_timeout: self.heartbeat_timeout.and_then(|d| d.try_into().ok()),
79
87
  cancellation_type: self.cancellation_type as i32,
80
88
  arguments: vec![self.input],
89
+ retry_policy: self.retry_policy,
81
90
  ..Default::default()
82
91
  }
83
92
  }
@@ -144,11 +153,15 @@ impl IntoWorkflowCommand for LocalActivityOptions {
144
153
  activity_type: self.activity_type,
145
154
  arguments: vec![self.input],
146
155
  retry_policy: Some(self.retry_policy),
147
- local_retry_threshold: self.timer_backoff_threshold.map(Into::into),
156
+ local_retry_threshold: self.timer_backoff_threshold.and_then(|d| d.try_into().ok()),
148
157
  cancellation_type: self.cancel_type.into(),
149
- schedule_to_close_timeout: self.schedule_to_close_timeout.map(Into::into),
150
- schedule_to_start_timeout: self.schedule_to_start_timeout.map(Into::into),
151
- start_to_close_timeout: self.start_to_close_timeout.map(Into::into),
158
+ schedule_to_close_timeout: self
159
+ .schedule_to_close_timeout
160
+ .and_then(|d| d.try_into().ok()),
161
+ schedule_to_start_timeout: self
162
+ .schedule_to_start_timeout
163
+ .and_then(|d| d.try_into().ok()),
164
+ start_to_close_timeout: self.start_to_close_timeout.and_then(|d| d.try_into().ok()),
152
165
  ..Default::default()
153
166
  }
154
167
  }
@@ -165,6 +178,8 @@ pub struct ChildWorkflowOptions {
165
178
  pub input: Vec<Payload>,
166
179
  /// Cancellation strategy for the child workflow
167
180
  pub cancel_type: ChildWorkflowCancellationType,
181
+ /// Common options
182
+ pub options: WorkflowOptions,
168
183
  }
169
184
 
170
185
  impl IntoWorkflowCommand for ChildWorkflowOptions {
@@ -176,6 +191,18 @@ impl IntoWorkflowCommand for ChildWorkflowOptions {
176
191
  workflow_type: self.workflow_type,
177
192
  input: self.input,
178
193
  cancellation_type: self.cancel_type as i32,
194
+ workflow_id_reuse_policy: self.options.id_reuse_policy as i32,
195
+ workflow_execution_timeout: self
196
+ .options
197
+ .execution_timeout
198
+ .and_then(|d| d.try_into().ok()),
199
+ workflow_run_timeout: self
200
+ .options
201
+ .execution_timeout
202
+ .and_then(|d| d.try_into().ok()),
203
+ workflow_task_timeout: self.options.task_timeout.and_then(|d| d.try_into().ok()),
204
+ search_attributes: self.options.search_attributes.unwrap_or_default(),
205
+ cron_schedule: self.options.cron_schedule.unwrap_or_default(),
179
206
  ..Default::default()
180
207
  }
181
208
  }
@@ -239,6 +266,7 @@ impl Signal {
239
266
  }
240
267
 
241
268
  /// Data contained within a signal
269
+ #[derive(Default)]
242
270
  pub struct SignalData {
243
271
  /// The arguments the signal will receive
244
272
  pub input: Vec<Payload>,
@@ -171,7 +171,11 @@ impl WfContext {
171
171
  CommandCreateRequest {
172
172
  cmd: StartTimer {
173
173
  seq,
174
- start_to_fire_timeout: Some(duration.into()),
174
+ start_to_fire_timeout: Some(
175
+ duration
176
+ .try_into()
177
+ .expect("Durations must fit into 64 bits"),
178
+ ),
175
179
  }
176
180
  .into(),
177
181
  unblocker,
@@ -294,13 +298,10 @@ impl WfContext {
294
298
  }
295
299
 
296
300
  /// Return a stream that produces values when the named signal is sent to this workflow
297
- pub fn make_signal_channel(
298
- &self,
299
- signal_name: impl Into<String>,
300
- ) -> impl Stream<Item = SignalData> {
301
+ pub fn make_signal_channel(&self, signal_name: impl Into<String>) -> DrainableSignalStream {
301
302
  let (tx, rx) = mpsc::unbounded_channel();
302
303
  self.send(RustWfCmd::SubscribeSignal(signal_name.into(), tx));
303
- UnboundedReceiverStream::new(rx)
304
+ DrainableSignalStream(UnboundedReceiverStream::new(rx))
304
305
  }
305
306
 
306
307
  /// Force a workflow task failure (EX: in order to retry on non-sticky queue)
@@ -366,6 +367,29 @@ impl WfContext {
366
367
  }
367
368
  }
368
369
 
370
+ /// Helper Wrapper that can drain the channel into a Vec<SignalData> in a blocking way. Useful
371
+ /// for making sure channels are empty before ContinueAsNew-ing a workflow
372
+ pub struct DrainableSignalStream(UnboundedReceiverStream<SignalData>);
373
+
374
+ impl DrainableSignalStream {
375
+ pub fn drain_all(self) -> Vec<SignalData> {
376
+ let mut receiver = self.0.into_inner();
377
+ let mut signals = vec![];
378
+ while let Ok(s) = receiver.try_recv() {
379
+ signals.push(s);
380
+ }
381
+ signals
382
+ }
383
+ }
384
+
385
+ impl Stream for DrainableSignalStream {
386
+ type Item = SignalData;
387
+
388
+ fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
389
+ Pin::new(&mut self.0).poll_next(cx)
390
+ }
391
+ }
392
+
369
393
  /// A Future that can be cancelled.
370
394
  /// Used in the prototype SDK for cancelling operations like timers and activities.
371
395
  pub trait CancellableFuture<T>: Future<Output = T> {
@@ -24,7 +24,7 @@ use temporal_sdk_core_protos::{
24
24
  },
25
25
  workflow_commands::{
26
26
  request_cancel_external_workflow_execution as cancel_we, workflow_command,
27
- CancelSignalWorkflow, CancelTimer, CancelUnstartedChildWorkflowExecution,
27
+ CancelChildWorkflowExecution, CancelSignalWorkflow, CancelTimer,
28
28
  CancelWorkflowExecution, CompleteWorkflowExecution, FailWorkflowExecution,
29
29
  RequestCancelActivity, RequestCancelExternalWorkflowExecution,
30
30
  RequestCancelLocalActivity, ScheduleActivity, ScheduleLocalActivity,
@@ -334,9 +334,9 @@ impl Future for WorkflowFuture {
334
334
  }
335
335
  CancellableID::ChildWorkflow(seq) => {
336
336
  activation_cmds.push(
337
- workflow_command::Variant::CancelUnstartedChildWorkflowExecution(
338
- CancelUnstartedChildWorkflowExecution {
339
- child_workflow_seq: seq
337
+ workflow_command::Variant::CancelChildWorkflowExecution(
338
+ CancelChildWorkflowExecution {
339
+ child_workflow_seq: seq,
340
340
  },
341
341
  ),
342
342
  );
@@ -17,14 +17,14 @@ history_builders = ["uuid", "rand"]
17
17
  anyhow = "1.0"
18
18
  base64 = "0.13"
19
19
  derive_more = "0.99"
20
- prost = "0.9"
21
- prost-types = "0.9"
20
+ prost = "0.11"
21
+ prost-types = "0.11"
22
22
  rand = { version = "0.8", optional = true }
23
23
  serde = { version = "1.0", features = ["derive"] }
24
24
  serde_json = "1.0"
25
25
  thiserror = "1.0"
26
- tonic = "0.6"
27
- uuid = { version = "0.8.2", features = ["v4"], optional = true }
26
+ tonic = "0.8"
27
+ uuid = { version = "1.1", features = ["v4"], optional = true }
28
28
 
29
29
  [build-dependencies]
30
- tonic-build = "0.6"
30
+ tonic-build = "0.8"
@@ -93,8 +93,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
93
93
  "../protos/local/temporal/sdk/core/core_interface.proto",
94
94
  "../protos/local/temporal/sdk/core/bridge/bridge.proto",
95
95
  "../protos/api_upstream/temporal/api/workflowservice/v1/service.proto",
96
+ "../protos/api_upstream/temporal/api/operatorservice/v1/service.proto",
97
+ "../protos/testsrv_upstream/temporal/api/testservice/v1/service.proto",
98
+ "../protos/grpc/health/v1/health.proto",
99
+ ],
100
+ &[
101
+ "../protos/api_upstream",
102
+ "../protos/local",
103
+ "../protos/testsrv_upstream",
104
+ "../protos/grpc",
96
105
  ],
97
- &["../protos/api_upstream", "../protos/local"],
98
106
  )?;
99
107
  Ok(())
100
108
  }
@@ -334,6 +334,7 @@ impl TestHistoryBuilder {
334
334
  failure_info: Some(failure::FailureInfo::CanceledFailureInfo(
335
335
  CanceledFailureInfo { details: None },
336
336
  )),
337
+ encoded_attributes: Default::default(),
337
338
  }),
338
339
  None,
339
340
  );
@@ -486,7 +487,11 @@ pub fn default_wes_attribs() -> WorkflowExecutionStartedEventAttributes {
486
487
  workflow_type: Some(WorkflowType {
487
488
  name: DEFAULT_WORKFLOW_TYPE.to_owned(),
488
489
  }),
489
- workflow_task_timeout: Some(Duration::from_secs(5).into()),
490
+ workflow_task_timeout: Some(
491
+ Duration::from_secs(5)
492
+ .try_into()
493
+ .expect("5 secs is a valid duration"),
494
+ ),
490
495
  ..Default::default()
491
496
  }
492
497
  }
@@ -17,7 +17,7 @@ pub use history_builder::{default_wes_attribs, TestHistoryBuilder, DEFAULT_WORKF
17
17
  pub use history_info::HistoryInfo;
18
18
  pub use task_token::TaskToken;
19
19
 
20
- #[allow(clippy::large_enum_variant)]
20
+ #[allow(clippy::large_enum_variant, clippy::derive_partial_eq_without_eq)]
21
21
  // I'd prefer not to do this, but there are some generated things that just don't need it.
22
22
  #[allow(missing_docs)]
23
23
  pub mod coresdk {
@@ -201,7 +201,8 @@ pub mod coresdk {
201
201
  pub fn timed_out(&self) -> bool {
202
202
  matches!(self.status, Some(activity_resolution::Status::Failed(Failure {
203
203
  failure: Some(ref f)
204
- })) if f.is_timeout())
204
+ })) if f.is_timeout()
205
+ || f.cause.as_ref().map(|c| c.is_timeout()).unwrap_or_default())
205
206
  }
206
207
 
207
208
  pub fn cancelled(&self) -> bool {
@@ -270,8 +271,9 @@ pub mod coresdk {
270
271
  pub fn decode_change_marker_details(
271
272
  details: &HashMap<String, Payloads>,
272
273
  ) -> Option<(String, bool)> {
273
- let name = std::str::from_utf8(&details.get("patch_id")?.payloads.get(0)?.data).ok()?;
274
- let deprecated = *details.get("deprecated")?.payloads.get(0)?.data.get(0)? != 0;
274
+ let name =
275
+ std::str::from_utf8(&details.get("patch_id")?.payloads.first()?.data).ok()?;
276
+ let deprecated = *details.get("deprecated")?.payloads.first()?.data.first()? != 0;
275
277
  Some((name.to_string(), deprecated))
276
278
  }
277
279
 
@@ -788,11 +790,11 @@ pub mod coresdk {
788
790
  }
789
791
  }
790
792
 
791
- impl Display for CancelUnstartedChildWorkflowExecution {
793
+ impl Display for CancelChildWorkflowExecution {
792
794
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
793
795
  write!(
794
796
  f,
795
- "CancelUnstartedChildWorkflowExecution({})",
797
+ "CancelChildWorkflowExecution({})",
796
798
  self.child_workflow_seq
797
799
  )
798
800
  }
@@ -1318,6 +1320,16 @@ pub mod coresdk {
1318
1320
  // This is disgusting, but unclear to me how to avoid it. TODO: Discuss w/ prost maintainer
1319
1321
  pub mod temporal {
1320
1322
  pub mod api {
1323
+ pub mod cluster {
1324
+ pub mod v1 {
1325
+ tonic::include_proto!("temporal.api.cluster.v1");
1326
+ }
1327
+ }
1328
+ pub mod batch {
1329
+ pub mod v1 {
1330
+ tonic::include_proto!("temporal.api.batch.v1");
1331
+ }
1332
+ }
1321
1333
  pub mod command {
1322
1334
  pub mod v1 {
1323
1335
  tonic::include_proto!("temporal.api.command.v1");
@@ -1488,9 +1500,22 @@ pub mod temporal {
1488
1500
  input: c.arguments.into_payloads(),
1489
1501
  workflow_run_timeout: c.workflow_run_timeout,
1490
1502
  workflow_task_timeout: c.workflow_task_timeout,
1491
- memo: Some(c.memo.into()),
1492
- header: Some(c.headers.into()),
1493
- search_attributes: Some(c.search_attributes.into()),
1503
+ memo: if c.memo.is_empty() {
1504
+ None
1505
+ } else {
1506
+ Some(c.memo.into())
1507
+ },
1508
+ header: if c.headers.is_empty() {
1509
+ None
1510
+ } else {
1511
+ Some(c.headers.into())
1512
+ },
1513
+ retry_policy: c.retry_policy,
1514
+ search_attributes: if c.search_attributes.is_empty() {
1515
+ None
1516
+ } else {
1517
+ Some(c.search_attributes.into())
1518
+ },
1494
1519
  ..Default::default()
1495
1520
  },
1496
1521
  )
@@ -1506,21 +1531,6 @@ pub mod temporal {
1506
1531
  }
1507
1532
  }
1508
1533
  }
1509
- pub mod enums {
1510
- pub mod v1 {
1511
- tonic::include_proto!("temporal.api.enums.v1");
1512
- }
1513
- }
1514
- pub mod failure {
1515
- pub mod v1 {
1516
- tonic::include_proto!("temporal.api.failure.v1");
1517
- }
1518
- }
1519
- pub mod filter {
1520
- pub mod v1 {
1521
- tonic::include_proto!("temporal.api.filter.v1");
1522
- }
1523
- }
1524
1534
  pub mod common {
1525
1535
  pub mod v1 {
1526
1536
  use std::{
@@ -1585,6 +1595,21 @@ pub mod temporal {
1585
1595
  }
1586
1596
  }
1587
1597
 
1598
+ impl From<Memo> for HashMap<String, Payload> {
1599
+ fn from(h: Memo) -> Self {
1600
+ h.fields.into_iter().map(|(k, v)| (k, v.into())).collect()
1601
+ }
1602
+ }
1603
+
1604
+ impl From<SearchAttributes> for HashMap<String, Payload> {
1605
+ fn from(h: SearchAttributes) -> Self {
1606
+ h.indexed_fields
1607
+ .into_iter()
1608
+ .map(|(k, v)| (k, v.into()))
1609
+ .collect()
1610
+ }
1611
+ }
1612
+
1588
1613
  impl From<HashMap<String, Payload>> for SearchAttributes {
1589
1614
  fn from(h: HashMap<String, Payload>) -> Self {
1590
1615
  Self {
@@ -1594,6 +1619,21 @@ pub mod temporal {
1594
1619
  }
1595
1620
  }
1596
1621
  }
1622
+ pub mod enums {
1623
+ pub mod v1 {
1624
+ tonic::include_proto!("temporal.api.enums.v1");
1625
+ }
1626
+ }
1627
+ pub mod failure {
1628
+ pub mod v1 {
1629
+ tonic::include_proto!("temporal.api.failure.v1");
1630
+ }
1631
+ }
1632
+ pub mod filter {
1633
+ pub mod v1 {
1634
+ tonic::include_proto!("temporal.api.filter.v1");
1635
+ }
1636
+ }
1597
1637
  pub mod history {
1598
1638
  pub mod v1 {
1599
1639
  use crate::temporal::api::{
@@ -1709,31 +1749,31 @@ pub mod temporal {
1709
1749
  }
1710
1750
  }
1711
1751
  }
1712
-
1713
1752
  pub mod namespace {
1714
1753
  pub mod v1 {
1715
1754
  tonic::include_proto!("temporal.api.namespace.v1");
1716
1755
  }
1717
1756
  }
1718
-
1757
+ pub mod operatorservice {
1758
+ pub mod v1 {
1759
+ tonic::include_proto!("temporal.api.operatorservice.v1");
1760
+ }
1761
+ }
1719
1762
  pub mod query {
1720
1763
  pub mod v1 {
1721
1764
  tonic::include_proto!("temporal.api.query.v1");
1722
1765
  }
1723
1766
  }
1724
-
1725
1767
  pub mod replication {
1726
1768
  pub mod v1 {
1727
1769
  tonic::include_proto!("temporal.api.replication.v1");
1728
1770
  }
1729
1771
  }
1730
-
1731
1772
  pub mod schedule {
1732
1773
  pub mod v1 {
1733
1774
  tonic::include_proto!("temporal.api.schedule.v1");
1734
1775
  }
1735
1776
  }
1736
-
1737
1777
  pub mod taskqueue {
1738
1778
  pub mod v1 {
1739
1779
  use crate::temporal::api::enums::v1::TaskQueueKind;
@@ -1749,19 +1789,26 @@ pub mod temporal {
1749
1789
  }
1750
1790
  }
1751
1791
  }
1752
-
1792
+ pub mod testservice {
1793
+ pub mod v1 {
1794
+ tonic::include_proto!("temporal.api.testservice.v1");
1795
+ }
1796
+ }
1797
+ pub mod update {
1798
+ pub mod v1 {
1799
+ tonic::include_proto!("temporal.api.update.v1");
1800
+ }
1801
+ }
1753
1802
  pub mod version {
1754
1803
  pub mod v1 {
1755
1804
  tonic::include_proto!("temporal.api.version.v1");
1756
1805
  }
1757
1806
  }
1758
-
1759
1807
  pub mod workflow {
1760
1808
  pub mod v1 {
1761
1809
  tonic::include_proto!("temporal.api.workflow.v1");
1762
1810
  }
1763
1811
  }
1764
-
1765
1812
  pub mod workflowservice {
1766
1813
  pub mod v1 {
1767
1814
  use std::{
@@ -1847,3 +1894,17 @@ pub mod temporal {
1847
1894
  }
1848
1895
  }
1849
1896
  }
1897
+
1898
+ #[allow(
1899
+ clippy::all,
1900
+ missing_docs,
1901
+ rustdoc::broken_intra_doc_links,
1902
+ rustdoc::bare_urls
1903
+ )]
1904
+ pub mod grpc {
1905
+ pub mod health {
1906
+ pub mod v1 {
1907
+ tonic::include_proto!("grpc.health.v1");
1908
+ }
1909
+ }
1910
+ }
@@ -15,8 +15,8 @@ base64 = "0.13"
15
15
  futures = "0.3"
16
16
  log = "0.4"
17
17
  parking_lot = "0.12"
18
- prost = "0.9"
19
- prost-types = "0.9"
18
+ prost = "0.11"
19
+ prost-types = "0.11"
20
20
  rand = "0.8"
21
21
  serde_json = "1.0"
22
22
  temporal-client = { path = "../client" }
@@ -28,7 +28,7 @@ tokio = "1.1"
28
28
  tokio-util = { version = "0.7" }
29
29
  tracing = "0.1"
30
30
  url = "2.2"
31
- uuid = "0.8"
31
+ uuid = "1.1"
32
32
 
33
33
  [dependencies.temporal-sdk-core-protos]
34
34
  path = "../sdk-core-protos"
@@ -1,4 +1,6 @@
1
+ use prost::Message;
1
2
  use rand::RngCore;
3
+ use std::{fs::File, io::Write, path::PathBuf};
2
4
  use temporal_sdk_core::replay::TestHistoryBuilder;
3
5
  use temporal_sdk_core_protos::{
4
6
  coresdk::common::NamespacedWorkflowExecution,
@@ -1430,6 +1432,49 @@ pub fn single_child_workflow_cancelled(child_wf_id: &str) -> TestHistoryBuilder
1430
1432
  t
1431
1433
  }
1432
1434
 
1435
+ /// 1: EVENT_TYPE_WORKFLOW_EXECUTION_STARTED
1436
+ /// 2: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
1437
+ /// 3: EVENT_TYPE_WORKFLOW_TASK_STARTED
1438
+ /// 4: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
1439
+ /// 5: EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED
1440
+ /// 6: EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED
1441
+ /// 7: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
1442
+ /// 8: EVENT_TYPE_WORKFLOW_TASK_STARTED
1443
+ /// 9: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
1444
+ /// 10: EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED
1445
+ pub fn single_child_workflow_abandon_cancelled(child_wf_id: &str) -> TestHistoryBuilder {
1446
+ let (mut t, _, _) = start_child_wf_preamble(child_wf_id);
1447
+ t.add_workflow_execution_completed();
1448
+ t
1449
+ }
1450
+
1451
+ /// 1: EVENT_TYPE_WORKFLOW_EXECUTION_STARTED
1452
+ /// 2: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
1453
+ /// 3: EVENT_TYPE_WORKFLOW_TASK_STARTED
1454
+ /// 4: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
1455
+ /// 5: EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED
1456
+ /// 6: EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED
1457
+ /// 7: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
1458
+ /// 8: EVENT_TYPE_WORKFLOW_TASK_STARTED
1459
+ /// 9: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
1460
+ /// 10: EVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED
1461
+ /// 11: EVENT_TYPE_EXTERNAL_WORKFLOW_EXECUTION_CANCEL_REQUESTED
1462
+ /// 12: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
1463
+ /// 13: EVENT_TYPE_WORKFLOW_TASK_STARTED
1464
+ /// 14: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
1465
+ /// 15: EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED
1466
+ pub fn single_child_workflow_try_cancelled(child_wf_id: &str) -> TestHistoryBuilder {
1467
+ let (mut t, _, _) = start_child_wf_preamble(child_wf_id);
1468
+ let id = t.add_cancel_external_wf(NamespacedWorkflowExecution {
1469
+ workflow_id: child_wf_id.to_string(),
1470
+ ..Default::default()
1471
+ });
1472
+ t.add_cancel_external_wf_completed(id);
1473
+ t.add_full_wf_task();
1474
+ t.add_workflow_execution_completed();
1475
+ t
1476
+ }
1477
+
1433
1478
  /// 1: EVENT_TYPE_WORKFLOW_EXECUTION_STARTED
1434
1479
  /// 2: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
1435
1480
  /// 3: EVENT_TYPE_WORKFLOW_TASK_STARTED
@@ -1519,3 +1564,16 @@ pub fn two_local_activities_separated_by_timer() -> TestHistoryBuilder {
1519
1564
  t.add_workflow_execution_completed();
1520
1565
  t
1521
1566
  }
1567
+
1568
+ /// Useful for one-of needs to write a crafted history to a file. Writes it as serialized proto
1569
+ /// binary to the provided path.
1570
+ pub fn write_hist_to_binfile(
1571
+ thb: &TestHistoryBuilder,
1572
+ file_path: PathBuf,
1573
+ ) -> Result<(), anyhow::Error> {
1574
+ let as_complete_hist: History = thb.get_full_history_info()?.into();
1575
+ let serialized = as_complete_hist.encode_to_vec();
1576
+ let mut file = File::create(file_path)?;
1577
+ file.write_all(&serialized)?;
1578
+ Ok(())
1579
+ }
@@ -160,6 +160,7 @@ impl CoreWfStarter {
160
160
  self.worker_config.task_queue.clone(),
161
161
  workflow_id,
162
162
  self.task_queue_name.clone(),
163
+ None,
163
164
  opts,
164
165
  )
165
166
  .await
@@ -319,6 +320,7 @@ impl TestWorker {
319
320
  self.inner.task_queue().to_string(),
320
321
  wfid.clone(),
321
322
  workflow_type.into(),
323
+ None,
322
324
  options,
323
325
  )
324
326
  .await?;
@@ -362,6 +364,8 @@ impl TestWorker {
362
364
  }
363
365
  }
364
366
 
367
+ pub type BoxDynActivationHook = Box<dyn Fn(&WorkflowActivationCompletion)>;
368
+
365
369
  pub enum TestWorkerShutdownCond {
366
370
  GetResults(Vec<WorkflowExecutionInfo>, Arc<RetryClient<Client>>),
367
371
  NoAutoShutdown,
@@ -370,7 +374,7 @@ pub enum TestWorkerShutdownCond {
370
374
  pub struct TestWorkerCompletionIceptor {
371
375
  condition: TestWorkerShutdownCond,
372
376
  shutdown_handle: Arc<dyn Fn()>,
373
- every_activation: Option<Box<dyn Fn(&WorkflowActivationCompletion)>>,
377
+ every_activation: Option<BoxDynActivationHook>,
374
378
  next: Option<Box<dyn WorkerInterceptor>>,
375
379
  }
376
380
  impl TestWorkerCompletionIceptor {
@@ -483,10 +487,10 @@ pub fn schedule_activity_cmd(
483
487
  activity_type: "test_activity".to_string(),
484
488
  namespace: NAMESPACE.to_owned(),
485
489
  task_queue: task_q.to_owned(),
486
- schedule_to_start_timeout: Some(activity_timeout.into()),
487
- start_to_close_timeout: Some(activity_timeout.into()),
488
- schedule_to_close_timeout: Some(activity_timeout.into()),
489
- heartbeat_timeout: Some(heartbeat_timeout.into()),
490
+ schedule_to_start_timeout: Some(activity_timeout.try_into().expect("duration fits")),
491
+ start_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
492
+ schedule_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
493
+ heartbeat_timeout: Some(heartbeat_timeout.try_into().expect("duration fits")),
490
494
  cancellation_type: cancellation_type as i32,
491
495
  ..Default::default()
492
496
  }
@@ -503,9 +507,9 @@ pub fn schedule_local_activity_cmd(
503
507
  seq,
504
508
  activity_id: activity_id.to_string(),
505
509
  activity_type: "test_activity".to_string(),
506
- schedule_to_start_timeout: Some(activity_timeout.into()),
507
- start_to_close_timeout: Some(activity_timeout.into()),
508
- schedule_to_close_timeout: Some(activity_timeout.into()),
510
+ schedule_to_start_timeout: Some(activity_timeout.try_into().expect("duration fits")),
511
+ start_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
512
+ schedule_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
509
513
  cancellation_type: cancellation_type as i32,
510
514
  ..Default::default()
511
515
  }
@@ -515,7 +519,7 @@ pub fn schedule_local_activity_cmd(
515
519
  pub fn start_timer_cmd(seq: u32, duration: Duration) -> workflow_command::Variant {
516
520
  StartTimer {
517
521
  seq,
518
- start_to_fire_timeout: Some(duration.into()),
522
+ start_to_fire_timeout: Some(duration.try_into().expect("duration fits")),
519
523
  }
520
524
  .into()
521
525
  }
@@ -565,7 +569,7 @@ where
565
569
  run_id.to_string(),
566
570
  vec![StartTimer {
567
571
  seq,
568
- start_to_fire_timeout: Some(duration.into()),
572
+ start_to_fire_timeout: Some(duration.try_into().expect("duration fits")),
569
573
  }
570
574
  .into()],
571
575
  ))