@temporalio/core-bridge 0.16.4 → 0.18.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 (170) hide show
  1. package/Cargo.lock +339 -226
  2. package/Cargo.toml +7 -3
  3. package/common.js +50 -0
  4. package/index.d.ts +7 -0
  5. package/index.js +12 -0
  6. package/package.json +7 -4
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/{index.node → releases/index.node} +0 -0
  10. package/releases/x86_64-apple-darwin/index.node +0 -0
  11. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  12. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  13. package/scripts/build.js +10 -50
  14. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  15. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  16. package/sdk-core/.buildkite/pipeline.yml +2 -0
  17. package/sdk-core/Cargo.toml +1 -88
  18. package/sdk-core/README.md +30 -6
  19. package/sdk-core/bridge-ffi/Cargo.toml +24 -0
  20. package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  21. package/sdk-core/bridge-ffi/build.rs +25 -0
  22. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
  23. package/sdk-core/bridge-ffi/src/lib.rs +829 -0
  24. package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
  25. package/sdk-core/client/Cargo.toml +32 -0
  26. package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
  27. package/sdk-core/client/src/metrics.rs +89 -0
  28. package/sdk-core/client/src/mocks.rs +167 -0
  29. package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
  30. package/sdk-core/core/Cargo.toml +96 -0
  31. package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
  32. package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
  33. package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
  34. package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
  35. package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
  36. package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
  37. package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
  38. package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
  39. package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
  40. package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
  41. package/sdk-core/core/src/lib.rs +374 -0
  42. package/sdk-core/{src → core/src}/log_export.rs +3 -27
  43. package/sdk-core/core/src/pending_activations.rs +162 -0
  44. package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
  45. package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
  46. package/sdk-core/core/src/protosext/mod.rs +396 -0
  47. package/sdk-core/core/src/replay/mod.rs +210 -0
  48. package/sdk-core/core/src/retry_logic.rs +144 -0
  49. package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
  50. package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
  51. package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
  52. package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
  53. package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
  55. package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
  56. package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
  57. package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
  58. package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
  59. package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
  60. package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
  61. package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
  62. package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
  63. package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
  64. package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
  65. package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
  66. package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
  67. package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
  68. package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
  69. package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
  70. package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
  71. package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
  72. package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
  73. package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
  74. package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
  75. package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
  76. package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
  77. package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
  78. package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
  79. package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
  80. package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
  81. package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
  82. package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
  83. package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
  84. package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
  85. package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
  86. package/sdk-core/{src → core-api/src}/errors.rs +42 -92
  87. package/sdk-core/core-api/src/lib.rs +158 -0
  88. package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
  89. package/sdk-core/etc/deps.svg +156 -0
  90. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
  92. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
  93. package/sdk-core/histories/fail_wf_task.bin +0 -0
  94. package/sdk-core/histories/timer_workflow_history.bin +0 -0
  95. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
  96. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
  97. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
  98. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
  99. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
  100. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
  101. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
  102. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
  103. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
  104. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  105. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
  106. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
  107. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
  108. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
  109. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  110. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
  111. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
  112. package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
  113. package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
  114. package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
  115. package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
  116. package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  117. package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
  118. package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
  119. package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
  120. package/sdk-core/sdk/Cargo.toml +32 -0
  121. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
  122. package/sdk-core/sdk/src/lib.rs +699 -0
  123. package/sdk-core/sdk/src/payload_converter.rs +11 -0
  124. package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
  125. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
  126. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
  127. package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
  128. package/sdk-core/sdk-core-protos/build.rs +28 -6
  129. package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  130. package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
  131. package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
  132. package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
  133. package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  134. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  135. package/sdk-core/test-utils/Cargo.toml +32 -0
  136. package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
  137. package/sdk-core/test-utils/src/histfetch.rs +28 -0
  138. package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
  139. package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
  140. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
  141. package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
  142. package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
  143. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
  144. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
  145. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
  146. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
  147. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
  148. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
  149. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
  150. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
  151. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
  152. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
  153. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
  154. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
  155. package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
  156. package/sdk-core/tests/load_tests.rs +6 -6
  157. package/sdk-core/tests/main.rs +2 -2
  158. package/src/conversions.rs +24 -21
  159. package/src/errors.rs +8 -0
  160. package/src/lib.rs +323 -211
  161. package/sdk-core/protos/local/activity_result.proto +0 -46
  162. package/sdk-core/protos/local/activity_task.proto +0 -66
  163. package/sdk-core/src/core_tests/retry.rs +0 -147
  164. package/sdk-core/src/lib.rs +0 -403
  165. package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
  166. package/sdk-core/src/pending_activations.rs +0 -249
  167. package/sdk-core/src/protosext/mod.rs +0 -160
  168. package/sdk-core/src/prototype_rust_sdk.rs +0 -412
  169. package/sdk-core/src/task_token.rs +0 -20
  170. package/sdk-core/src/test_help/history_info.rs +0 -157
@@ -1,9 +1,6 @@
1
1
  use crate::{
2
- prototype_rust_sdk::{
3
- conversions::anyhow_to_fail, workflow_context::WfContextSharedData, CancellableID,
4
- RustWfCmd, UnblockEvent, WfContext, WfExitValue, WorkflowFunction, WorkflowResult,
5
- },
6
- workflow::CommandID,
2
+ conversions::anyhow_to_fail, workflow_context::WfContextSharedData, CancellableID, RustWfCmd,
3
+ TimerResult, UnblockEvent, WfContext, WfExitValue, WorkflowFunction, WorkflowResult,
7
4
  };
8
5
  use anyhow::{anyhow, bail, Context as AnyhowContext, Error};
9
6
  use crossbeam::channel::Receiver;
@@ -21,20 +18,22 @@ use temporal_sdk_core_protos::{
21
18
  coresdk::{
22
19
  common::Payload,
23
20
  workflow_activation::{
24
- wf_activation_job::Variant, FireTimer, NotifyHasPatch, ResolveActivity,
25
- ResolveChildWorkflowExecution, ResolveChildWorkflowExecutionStart, WfActivation,
26
- WfActivationJob,
21
+ workflow_activation_job::Variant, FireTimer, NotifyHasPatch, ResolveActivity,
22
+ ResolveChildWorkflowExecution, ResolveChildWorkflowExecutionStart, WorkflowActivation,
23
+ WorkflowActivationJob,
27
24
  },
28
25
  workflow_commands::{
29
26
  request_cancel_external_workflow_execution as cancel_we, workflow_command,
30
27
  CancelSignalWorkflow, CancelTimer, CancelUnstartedChildWorkflowExecution,
31
28
  CancelWorkflowExecution, CompleteWorkflowExecution, FailWorkflowExecution,
32
- RequestCancelActivity, RequestCancelExternalWorkflowExecution, ScheduleActivity,
29
+ RequestCancelActivity, RequestCancelExternalWorkflowExecution,
30
+ RequestCancelLocalActivity, ScheduleActivity, ScheduleLocalActivity,
33
31
  StartChildWorkflowExecution, StartTimer,
34
32
  },
35
- workflow_completion::WfActivationCompletion,
33
+ workflow_completion::WorkflowActivationCompletion,
36
34
  },
37
35
  temporal::api::failure::v1::Failure,
36
+ utilities::TryIntoOrNone,
38
37
  };
39
38
  use tokio::sync::{
40
39
  mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
@@ -42,18 +41,22 @@ use tokio::sync::{
42
41
  };
43
42
 
44
43
  impl WorkflowFunction {
45
- pub(crate) fn start_workflow(
44
+ /// Start a workflow function, returning a future that will resolve when the workflow does,
45
+ /// and a channel that can be used to send it activations.
46
+ #[doc(hidden)]
47
+ pub fn start_workflow(
46
48
  &self,
47
49
  namespace: String,
48
50
  task_queue: String,
49
51
  args: Vec<Payload>,
50
- outgoing_completions: UnboundedSender<WfActivationCompletion>,
52
+ outgoing_completions: UnboundedSender<WorkflowActivationCompletion>,
51
53
  ) -> (
52
54
  impl Future<Output = WorkflowResult<()>>,
53
- UnboundedSender<WfActivation>,
55
+ UnboundedSender<WorkflowActivation>,
54
56
  ) {
55
57
  let (cancel_tx, cancel_rx) = watch::channel(false);
56
- let (wf_context, cmd_receiver) = WfContext::new(namespace, args, cancel_rx);
58
+ let (wf_context, cmd_receiver) =
59
+ WfContext::new(namespace, task_queue.clone(), args, cancel_rx);
57
60
  let (tx, incoming_activations) = unbounded_channel();
58
61
  (
59
62
  WorkflowFuture {
@@ -97,9 +100,9 @@ pub struct WorkflowFuture {
97
100
  /// Commands produced inside user's wf code
98
101
  incoming_commands: Receiver<RustWfCmd>,
99
102
  /// Once blocked or the workflow has finished or errored out, the result is sent here
100
- outgoing_completions: UnboundedSender<WfActivationCompletion>,
103
+ outgoing_completions: UnboundedSender<WorkflowActivationCompletion>,
101
104
  /// Activations from core
102
- incoming_activations: UnboundedReceiver<WfActivation>,
105
+ incoming_activations: UnboundedReceiver<WorkflowActivation>,
103
106
  /// Commands by ID -> blocked status
104
107
  command_status: HashMap<CommandID, WFCommandFutInfo>,
105
108
  /// Use to notify workflow code of cancellation
@@ -115,7 +118,7 @@ pub struct WorkflowFuture {
115
118
  impl WorkflowFuture {
116
119
  fn unblock(&mut self, event: UnblockEvent) -> Result<(), Error> {
117
120
  let cmd_id = match event {
118
- UnblockEvent::Timer(seq) => CommandID::Timer(seq),
121
+ UnblockEvent::Timer(seq, _) => CommandID::Timer(seq),
119
122
  UnblockEvent::Activity(seq, _) => CommandID::Activity(seq),
120
123
  UnblockEvent::WorkflowStart(seq, _) => CommandID::ChildWorkflowStart(seq),
121
124
  UnblockEvent::WorkflowComplete(seq, _) => CommandID::ChildWorkflowComplete(seq),
@@ -134,7 +137,7 @@ impl WorkflowFuture {
134
137
  fn fail_wft(&self, run_id: String, fail: Error) {
135
138
  warn!("Workflow task failed for {}: {}", run_id, fail);
136
139
  self.outgoing_completions
137
- .send(WfActivationCompletion::fail(
140
+ .send(WorkflowActivationCompletion::fail(
138
141
  &self.task_queue,
139
142
  run_id,
140
143
  anyhow_to_fail(fail),
@@ -144,7 +147,7 @@ impl WorkflowFuture {
144
147
 
145
148
  fn send_completion(&self, run_id: String, activation_cmds: Vec<workflow_command::Variant>) {
146
149
  self.outgoing_completions
147
- .send(WfActivationCompletion::from_cmds(
150
+ .send(WorkflowActivationCompletion::from_cmds(
148
151
  &self.task_queue,
149
152
  run_id,
150
153
  activation_cmds,
@@ -164,7 +167,9 @@ impl WorkflowFuture {
164
167
  Variant::StartWorkflow(_) => {
165
168
  // TODO: Can assign randomness seed whenever needed
166
169
  }
167
- Variant::FireTimer(FireTimer { seq }) => self.unblock(UnblockEvent::Timer(seq))?,
170
+ Variant::FireTimer(FireTimer { seq }) => {
171
+ self.unblock(UnblockEvent::Timer(seq, TimerResult::Fired))?
172
+ }
168
173
  Variant::ResolveActivity(ResolveActivity { seq, result }) => {
169
174
  self.unblock(UnblockEvent::Activity(
170
175
  seq,
@@ -240,10 +245,14 @@ impl Future for WorkflowFuture {
240
245
 
241
246
  let is_only_eviction = activation.is_only_eviction();
242
247
  let run_id = activation.run_id;
243
- self.ctx_shared.write().is_replaying = activation.is_replaying;
248
+ {
249
+ let mut wlock = self.ctx_shared.write();
250
+ wlock.is_replaying = activation.is_replaying;
251
+ wlock.wf_time = activation.timestamp.try_into_or_none();
252
+ }
244
253
 
245
254
  let mut die_of_eviction_when_done = false;
246
- for WfActivationJob { variant } in activation.jobs {
255
+ for WorkflowActivationJob { variant } in activation.jobs {
247
256
  match self.handle_job(variant) {
248
257
  Ok(true) => {
249
258
  die_of_eviction_when_done = true;
@@ -259,7 +268,7 @@ impl Future for WorkflowFuture {
259
268
  if is_only_eviction {
260
269
  // No need to do anything with the workflow code in this case
261
270
  self.outgoing_completions
262
- .send(WfActivationCompletion::from_cmds(
271
+ .send(WorkflowActivationCompletion::from_cmds(
263
272
  &self.task_queue,
264
273
  run_id,
265
274
  vec![],
@@ -274,12 +283,18 @@ impl Future for WorkflowFuture {
274
283
  .poll_unpin(cx)
275
284
  {
276
285
  Poll::Ready(Err(e)) => {
286
+ let errmsg = format!(
287
+ "Workflow function panicked: {:?}",
288
+ // Panics are typically strings
289
+ e.downcast::<String>()
290
+ );
291
+ warn!("{}", errmsg);
277
292
  self.outgoing_completions
278
- .send(WfActivationCompletion::fail(
293
+ .send(WorkflowActivationCompletion::fail(
279
294
  &self.task_queue,
280
295
  run_id,
281
296
  Failure {
282
- message: format!("Workflow function panicked: {:?}", e),
297
+ message: errmsg,
283
298
  ..Default::default()
284
299
  },
285
300
  ))
@@ -300,9 +315,7 @@ impl Future for WorkflowFuture {
300
315
  activation_cmds.push(workflow_command::Variant::CancelTimer(
301
316
  CancelTimer { seq },
302
317
  ));
303
- // TODO: cancelled timer should not simply be unblocked, in the
304
- // other SDKs this returns an error
305
- self.unblock(UnblockEvent::Timer(seq))?;
318
+ self.unblock(UnblockEvent::Timer(seq, TimerResult::Cancelled))?;
306
319
  // Re-poll wf future since a timer is now unblocked
307
320
  res = self.inner.poll_unpin(cx);
308
321
  }
@@ -313,6 +326,13 @@ impl Future for WorkflowFuture {
313
326
  ),
314
327
  );
315
328
  }
329
+ CancellableID::LocalActivity(seq) => {
330
+ activation_cmds.push(
331
+ workflow_command::Variant::RequestCancelLocalActivity(
332
+ RequestCancelLocalActivity { seq },
333
+ ),
334
+ );
335
+ }
316
336
  CancellableID::ChildWorkflow(seq) => {
317
337
  activation_cmds.push(
318
338
  workflow_command::Variant::CancelUnstartedChildWorkflowExecution(
@@ -359,7 +379,10 @@ impl Future for WorkflowFuture {
359
379
  workflow_command::Variant::ScheduleActivity(ScheduleActivity {
360
380
  seq,
361
381
  ..
362
- }) => CommandID::Activity(seq),
382
+ })
383
+ | workflow_command::Variant::ScheduleLocalActivity(
384
+ ScheduleLocalActivity { seq, .. },
385
+ ) => CommandID::Activity(seq),
363
386
  workflow_command::Variant::SetPatchMarker(_) => {
364
387
  panic!("Set patch marker should be a nonblocking command")
365
388
  }
@@ -427,7 +450,7 @@ impl Future for WorkflowFuture {
427
450
  ),
428
451
  );
429
452
  }
430
- WfExitValue::ContinueAsNew(cmd) => activation_cmds.push(cmd.into()),
453
+ WfExitValue::ContinueAsNew(cmd) => activation_cmds.push((*cmd).into()),
431
454
  WfExitValue::Cancelled => {
432
455
  activation_cmds.push(
433
456
  workflow_command::Variant::CancelWorkflowExecution(
@@ -469,3 +492,13 @@ impl Future for WorkflowFuture {
469
492
  }
470
493
  }
471
494
  }
495
+
496
+ #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
497
+ enum CommandID {
498
+ Timer(u32),
499
+ Activity(u32),
500
+ ChildWorkflowStart(u32),
501
+ ChildWorkflowComplete(u32),
502
+ SignalExternal(u32),
503
+ CancelExternal(u32),
504
+ }
@@ -10,11 +10,21 @@ repository = "https://github.com/temporalio/sdk-core"
10
10
  keywords = ["temporal", "workflow"]
11
11
  categories = ["development-tools"]
12
12
 
13
+ [features]
14
+ history_builders = ["uuid", "rand"]
15
+
13
16
  [dependencies]
17
+ anyhow = "1.0"
18
+ base64 = "0.13"
14
19
  derive_more = "0.99"
15
20
  prost = "0.9"
16
21
  prost-types = "0.9"
22
+ rand = { version = "0.8", optional = true }
23
+ serde = { version = "1.0", features = ["derive"] }
24
+ serde_json = "1.0"
25
+ thiserror = "1.0"
17
26
  tonic = "0.6"
27
+ uuid = { version = "0.8.2", features = ["v4"], optional = true }
18
28
 
19
29
  [build-dependencies]
20
30
  tonic-build = "0.5"
@@ -39,26 +39,30 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
39
39
  )
40
40
  .type_attribute(
41
41
  "coresdk.workflow_commands.WorkflowCommand.variant",
42
- "#[derive(::derive_more::From)]",
42
+ "#[derive(::derive_more::From, ::derive_more::Display)]",
43
43
  )
44
44
  .type_attribute(
45
45
  "coresdk.workflow_commands.QueryResult.variant",
46
46
  "#[derive(::derive_more::From)]",
47
47
  )
48
48
  .type_attribute(
49
- "coresdk.workflow_activation.wf_activation_job",
49
+ "coresdk.workflow_activation.workflow_activation_job",
50
50
  "#[derive(::derive_more::From)]",
51
51
  )
52
52
  .type_attribute(
53
- "coresdk.workflow_activation.WFActivationJob.variant",
53
+ "coresdk.workflow_activation.WorkflowActivationJob.variant",
54
54
  "#[derive(::derive_more::From)]",
55
55
  )
56
56
  .type_attribute(
57
- "coresdk.workflow_completion.WFActivationCompletion.status",
57
+ "coresdk.workflow_completion.WorkflowActivationCompletion.status",
58
58
  "#[derive(::derive_more::From)]",
59
59
  )
60
60
  .type_attribute(
61
- "coresdk.activity_result.ActivityResult.status",
61
+ "coresdk.activity_result.ActivityExecutionResult.status",
62
+ "#[derive(::derive_more::From)]",
63
+ )
64
+ .type_attribute(
65
+ "coresdk.activity_result.ActivityResolution.status",
62
66
  "#[derive(::derive_more::From)]",
63
67
  )
64
68
  .type_attribute(
@@ -66,9 +70,27 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
66
70
  "#[derive(::derive_more::Display)]",
67
71
  )
68
72
  .type_attribute("coresdk.Task.variant", "#[derive(::derive_more::From)]")
73
+ // All external data is useful to be able to JSON serialize, so it can render in web UI
74
+ .type_attribute(
75
+ ".coresdk.external_data",
76
+ "#[derive(::serde::Serialize, ::serde::Deserialize)]",
77
+ )
78
+ .field_attribute(
79
+ "coresdk.external_data.LocalActivityMarkerData.complete_time",
80
+ "#[serde(with = \"opt_timestamp\")]",
81
+ )
82
+ .field_attribute(
83
+ "coresdk.external_data.LocalActivityMarkerData.original_schedule_time",
84
+ "#[serde(with = \"opt_timestamp\")]",
85
+ )
86
+ .field_attribute(
87
+ "coresdk.external_data.LocalActivityMarkerData.backoff",
88
+ "#[serde(with = \"opt_duration\")]",
89
+ )
69
90
  .compile(
70
91
  &[
71
- "../protos/local/core_interface.proto",
92
+ "../protos/local/temporal/sdk/core/core_interface.proto",
93
+ "../protos/local/temporal/sdk/core/bridge/bridge.proto",
72
94
  "../protos/api_upstream/temporal/api/workflowservice/v1/service.proto",
73
95
  ],
74
96
  &["../protos/api_upstream", "../protos/local"],
@@ -0,0 +1,7 @@
1
+ //! Contains various constants that are used by core when storing/serializing data
2
+
3
+ /// Used as `marker_name` field when recording patch markers
4
+ pub const PATCH_MARKER_NAME: &str = "core_patch";
5
+
6
+ /// Used as `marker_name` field when recording local activity markers
7
+ pub const LOCAL_ACTIVITY_MARKER_NAME: &str = "core_local_activity";
@@ -1,27 +1,30 @@
1
1
  use crate::{
2
- machines::HAS_CHANGE_MARKER_NAME,
3
- test_help::{
4
- history_info::{HistoryInfo, HistoryInfoError},
5
- Result,
2
+ constants::{LOCAL_ACTIVITY_MARKER_NAME, PATCH_MARKER_NAME},
3
+ coresdk::{
4
+ common::{
5
+ build_has_change_marker_details, build_local_activity_marker_details,
6
+ NamespacedWorkflowExecution, Payload as CorePayload,
7
+ },
8
+ external_data::LocalActivityMarkerData,
9
+ IntoPayloadsExt,
6
10
  },
7
- workflow::HistoryUpdate,
8
- };
9
- use anyhow::bail;
10
- use std::time::SystemTime;
11
- use temporal_sdk_core_protos::{
12
- coresdk::common::{
13
- build_has_change_marker_details, NamespacedWorkflowExecution, Payload as CorePayload,
14
- },
15
- coresdk::IntoPayloadsExt,
16
11
  temporal::api::{
17
12
  common::v1::{Payload, Payloads, WorkflowExecution, WorkflowType},
18
13
  enums::v1::{EventType, WorkflowTaskFailedCause},
19
- failure::v1::Failure,
14
+ failure::v1::{failure, CanceledFailureInfo, Failure},
20
15
  history::v1::{history_event::Attributes, *},
21
16
  },
17
+ HistoryInfo,
22
18
  };
19
+ use anyhow::bail;
20
+ use prost_types::Timestamp;
21
+ use std::time::{Duration, SystemTime};
23
22
  use uuid::Uuid;
24
23
 
24
+ pub static DEFAULT_WORKFLOW_TYPE: &str = "default_wf_type";
25
+
26
+ type Result<T, E = anyhow::Error> = std::result::Result<T, E>;
27
+
25
28
  #[derive(Default, Clone, Debug)]
26
29
  pub struct TestHistoryBuilder {
27
30
  events: Vec<HistoryEvent>,
@@ -30,7 +33,6 @@ pub struct TestHistoryBuilder {
30
33
  current_event_id: i64,
31
34
  workflow_task_scheduled_event_id: i64,
32
35
  final_workflow_task_started_event_id: i64,
33
- previous_started_event_id: i64,
34
36
  previous_task_completed_id: i64,
35
37
  original_run_id: String,
36
38
  }
@@ -76,8 +78,6 @@ impl TestHistoryBuilder {
76
78
  }
77
79
 
78
80
  pub fn add_workflow_task_scheduled(&mut self) {
79
- // WFStarted always immediately follows WFScheduled
80
- self.previous_started_event_id = self.workflow_task_scheduled_event_id + 1;
81
81
  self.workflow_task_scheduled_event_id =
82
82
  self.add_get_event_id(EventType::WorkflowTaskScheduled, None);
83
83
  }
@@ -100,7 +100,7 @@ impl TestHistoryBuilder {
100
100
  self.previous_task_completed_id = id;
101
101
  }
102
102
 
103
- pub(crate) fn add_workflow_task_timed_out(&mut self) {
103
+ pub fn add_workflow_task_timed_out(&mut self) {
104
104
  let attrs = WorkflowTaskTimedOutEventAttributes {
105
105
  scheduled_event_id: self.workflow_task_scheduled_event_id,
106
106
  ..Default::default()
@@ -221,6 +221,16 @@ impl TestHistoryBuilder {
221
221
  self.build_and_push_event(EventType::WorkflowTaskFailed, attrs.into());
222
222
  }
223
223
 
224
+ pub fn add_timer_fired(&mut self, timer_started_evt_id: i64, timer_id: String) {
225
+ self.add(
226
+ EventType::TimerFired,
227
+ history_event::Attributes::TimerFiredEventAttributes(TimerFiredEventAttributes {
228
+ started_event_id: timer_started_evt_id,
229
+ timer_id,
230
+ }),
231
+ );
232
+ }
233
+
224
234
  pub fn add_we_signaled(&mut self, signal_name: &str, payloads: Vec<Payload>) {
225
235
  let attrs = WorkflowExecutionSignaledEventAttributes {
226
236
  signal_name: signal_name.to_string(),
@@ -230,9 +240,9 @@ impl TestHistoryBuilder {
230
240
  self.build_and_push_event(EventType::WorkflowExecutionSignaled, attrs.into());
231
241
  }
232
242
 
233
- pub(crate) fn add_has_change_marker(&mut self, patch_id: &str, deprecated: bool) {
243
+ pub fn add_has_change_marker(&mut self, patch_id: &str, deprecated: bool) {
234
244
  let attrs = MarkerRecordedEventAttributes {
235
- marker_name: HAS_CHANGE_MARKER_NAME.to_string(),
245
+ marker_name: PATCH_MARKER_NAME.to_string(),
236
246
  details: build_has_change_marker_details(patch_id, deprecated),
237
247
  workflow_task_completed_event_id: self.previous_task_completed_id,
238
248
  ..Default::default()
@@ -240,7 +250,82 @@ impl TestHistoryBuilder {
240
250
  self.build_and_push_event(EventType::MarkerRecorded, attrs.into());
241
251
  }
242
252
 
243
- pub(crate) fn add_signal_wf(
253
+ fn add_local_activity_marker(
254
+ &mut self,
255
+ seq: u32,
256
+ activity_id: &str,
257
+ payload: Option<CorePayload>,
258
+ failure: Option<Failure>,
259
+ complete_time: Option<Timestamp>,
260
+ ) {
261
+ let attrs = MarkerRecordedEventAttributes {
262
+ marker_name: LOCAL_ACTIVITY_MARKER_NAME.to_string(),
263
+ details: build_local_activity_marker_details(
264
+ LocalActivityMarkerData {
265
+ seq,
266
+ attempt: 1,
267
+ activity_id: activity_id.to_string(),
268
+ activity_type: "some_act_type".to_string(),
269
+ complete_time,
270
+ backoff: None,
271
+ original_schedule_time: None,
272
+ },
273
+ payload,
274
+ ),
275
+ workflow_task_completed_event_id: self.previous_task_completed_id,
276
+ failure,
277
+ ..Default::default()
278
+ };
279
+ self.build_and_push_event(EventType::MarkerRecorded, attrs.into());
280
+ }
281
+
282
+ pub fn add_local_activity_result_marker(
283
+ &mut self,
284
+ seq: u32,
285
+ activity_id: &str,
286
+ payload: CorePayload,
287
+ ) {
288
+ self.add_local_activity_marker(seq, activity_id, Some(payload), None, None);
289
+ }
290
+
291
+ pub fn add_local_activity_result_marker_with_time(
292
+ &mut self,
293
+ seq: u32,
294
+ activity_id: &str,
295
+ payload: CorePayload,
296
+ complete_time: Timestamp,
297
+ ) {
298
+ self.add_local_activity_marker(seq, activity_id, Some(payload), None, Some(complete_time));
299
+ }
300
+
301
+ pub fn add_local_activity_fail_marker(
302
+ &mut self,
303
+ seq: u32,
304
+ activity_id: &str,
305
+ failure: Failure,
306
+ ) {
307
+ self.add_local_activity_marker(seq, activity_id, None, Some(failure), None);
308
+ }
309
+
310
+ pub fn add_local_activity_cancel_marker(&mut self, seq: u32, activity_id: &str) {
311
+ self.add_local_activity_marker(
312
+ seq,
313
+ activity_id,
314
+ None,
315
+ Some(Failure {
316
+ message: "cancelled bro".to_string(),
317
+ source: "".to_string(),
318
+ stack_trace: "".to_string(),
319
+ cause: None,
320
+ failure_info: Some(failure::FailureInfo::CanceledFailureInfo(
321
+ CanceledFailureInfo { details: None },
322
+ )),
323
+ }),
324
+ None,
325
+ );
326
+ }
327
+
328
+ pub fn add_signal_wf(
244
329
  &mut self,
245
330
  signal_name: impl Into<String>,
246
331
  workflow_id: impl Into<String>,
@@ -262,7 +347,7 @@ impl TestHistoryBuilder {
262
347
  )
263
348
  }
264
349
 
265
- pub(crate) fn add_external_signal_completed(&mut self, initiated_id: i64) {
350
+ pub fn add_external_signal_completed(&mut self, initiated_id: i64) {
266
351
  let attrs = ExternalWorkflowExecutionSignaledEventAttributes {
267
352
  initiated_event_id: initiated_id,
268
353
  ..Default::default()
@@ -270,7 +355,7 @@ impl TestHistoryBuilder {
270
355
  self.build_and_push_event(EventType::ExternalWorkflowExecutionSignaled, attrs.into());
271
356
  }
272
357
 
273
- pub(crate) fn add_external_signal_failed(&mut self, initiated_id: i64) {
358
+ pub fn add_external_signal_failed(&mut self, initiated_id: i64) {
274
359
  let attrs = SignalExternalWorkflowExecutionFailedEventAttributes {
275
360
  initiated_event_id: initiated_id,
276
361
  ..Default::default()
@@ -281,7 +366,7 @@ impl TestHistoryBuilder {
281
366
  );
282
367
  }
283
368
 
284
- pub(crate) fn add_cancel_external_wf(&mut self, execution: NamespacedWorkflowExecution) -> i64 {
369
+ pub fn add_cancel_external_wf(&mut self, execution: NamespacedWorkflowExecution) -> i64 {
285
370
  let attrs = RequestCancelExternalWorkflowExecutionInitiatedEventAttributes {
286
371
  workflow_task_completed_event_id: self.previous_task_completed_id,
287
372
  namespace: execution.namespace,
@@ -297,7 +382,7 @@ impl TestHistoryBuilder {
297
382
  )
298
383
  }
299
384
 
300
- pub(crate) fn add_cancel_external_wf_completed(&mut self, initiated_id: i64) {
385
+ pub fn add_cancel_external_wf_completed(&mut self, initiated_id: i64) {
301
386
  let attrs = ExternalWorkflowExecutionCancelRequestedEventAttributes {
302
387
  initiated_event_id: initiated_id,
303
388
  ..Default::default()
@@ -308,7 +393,7 @@ impl TestHistoryBuilder {
308
393
  );
309
394
  }
310
395
 
311
- pub(crate) fn add_cancel_external_wf_failed(&mut self, initiated_id: i64) {
396
+ pub fn add_cancel_external_wf_failed(&mut self, initiated_id: i64) {
312
397
  let attrs = RequestCancelExternalWorkflowExecutionFailedEventAttributes {
313
398
  initiated_event_id: initiated_id,
314
399
  ..Default::default()
@@ -319,39 +404,37 @@ impl TestHistoryBuilder {
319
404
  );
320
405
  }
321
406
 
322
- pub(crate) fn as_history_update(&self) -> HistoryUpdate {
323
- self.get_full_history_info().unwrap().into()
324
- }
325
-
326
407
  pub fn get_orig_run_id(&self) -> &str {
327
408
  &self.original_run_id
328
409
  }
329
410
 
330
411
  /// Iterates over the events in this builder to return a [HistoryInfo] including events up to
331
412
  /// the provided `to_wf_task_num`
332
- pub(crate) fn get_history_info(
333
- &self,
334
- to_wf_task_num: usize,
335
- ) -> Result<HistoryInfo, HistoryInfoError> {
413
+ pub fn get_history_info(&self, to_wf_task_num: usize) -> Result<HistoryInfo, anyhow::Error> {
336
414
  HistoryInfo::new_from_history(&self.events.clone().into(), Some(to_wf_task_num))
337
415
  }
338
416
 
339
417
  /// Iterates over the events in this builder to return a [HistoryInfo] representing *all*
340
418
  /// events in the history
341
- pub(crate) fn get_full_history_info(&self) -> Result<HistoryInfo, HistoryInfoError> {
419
+ pub fn get_full_history_info(&self) -> Result<HistoryInfo, anyhow::Error> {
342
420
  HistoryInfo::new_from_history(&self.events.clone().into(), None)
343
421
  }
344
422
 
345
- pub(crate) fn get_one_wft(
346
- &self,
347
- from_wft_number: usize,
348
- ) -> Result<HistoryInfo, HistoryInfoError> {
423
+ pub fn get_one_wft(&self, from_wft_number: usize) -> Result<HistoryInfo, anyhow::Error> {
349
424
  let mut histinfo =
350
425
  HistoryInfo::new_from_history(&self.events.clone().into(), Some(from_wft_number))?;
351
426
  histinfo.make_incremental();
352
427
  Ok(histinfo)
353
428
  }
354
429
 
430
+ /// Return most recent wft start time or panic if unset
431
+ pub fn wft_start_time(&self) -> prost_types::Timestamp {
432
+ self.events[(self.workflow_task_scheduled_event_id + 1) as usize]
433
+ .event_time
434
+ .clone()
435
+ .unwrap()
436
+ }
437
+
355
438
  fn build_and_push_event(&mut self, event_type: EventType, attribs: Attributes) {
356
439
  self.current_event_id += 1;
357
440
  let evt = HistoryEvent {
@@ -374,20 +457,22 @@ impl TestHistoryBuilder {
374
457
  }
375
458
  }
376
459
 
377
- pub static DEFAULT_WORKFLOW_TYPE: &str = "not_specified";
378
-
379
460
  fn default_attribs(et: EventType) -> Result<Attributes> {
380
461
  Ok(match et {
381
- EventType::WorkflowExecutionStarted => WorkflowExecutionStartedEventAttributes {
382
- original_execution_run_id: Uuid::new_v4().to_string(),
383
- workflow_type: Some(WorkflowType {
384
- name: DEFAULT_WORKFLOW_TYPE.to_owned(),
385
- }),
386
- ..Default::default()
387
- }
388
- .into(),
462
+ EventType::WorkflowExecutionStarted => default_wes_attribs().into(),
389
463
  EventType::WorkflowTaskScheduled => WorkflowTaskScheduledEventAttributes::default().into(),
390
464
  EventType::TimerStarted => TimerStartedEventAttributes::default().into(),
391
465
  _ => bail!("Don't know how to construct default attrs for {:?}", et),
392
466
  })
393
467
  }
468
+
469
+ pub fn default_wes_attribs() -> WorkflowExecutionStartedEventAttributes {
470
+ WorkflowExecutionStartedEventAttributes {
471
+ original_execution_run_id: Uuid::new_v4().to_string(),
472
+ workflow_type: Some(WorkflowType {
473
+ name: DEFAULT_WORKFLOW_TYPE.to_owned(),
474
+ }),
475
+ workflow_task_timeout: Some(Duration::from_secs(5).into()),
476
+ ..Default::default()
477
+ }
478
+ }