@temporalio/core-bridge 1.11.0 → 1.11.2

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 (75) hide show
  1. package/Cargo.lock +86 -88
  2. package/lib/index.d.ts +3 -0
  3. package/lib/index.js.map +1 -1
  4. package/package.json +3 -3
  5. package/releases/aarch64-apple-darwin/index.node +0 -0
  6. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  7. package/releases/x86_64-apple-darwin/index.node +0 -0
  8. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  9. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  10. package/sdk-core/.github/workflows/per-pr.yml +7 -1
  11. package/sdk-core/Cargo.toml +1 -1
  12. package/sdk-core/client/Cargo.toml +3 -3
  13. package/sdk-core/client/src/lib.rs +1 -1
  14. package/sdk-core/client/src/metrics.rs +2 -2
  15. package/sdk-core/client/src/raw.rs +39 -13
  16. package/sdk-core/client/src/retry.rs +108 -62
  17. package/sdk-core/client/src/workflow_handle/mod.rs +1 -2
  18. package/sdk-core/core/Cargo.toml +4 -5
  19. package/sdk-core/core/src/abstractions.rs +2 -3
  20. package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
  21. package/sdk-core/core/src/core_tests/local_activities.rs +2 -2
  22. package/sdk-core/core/src/core_tests/queries.rs +8 -4
  23. package/sdk-core/core/src/core_tests/updates.rs +2 -2
  24. package/sdk-core/core/src/core_tests/workflow_cancels.rs +3 -3
  25. package/sdk-core/core/src/core_tests/workflow_tasks.rs +55 -54
  26. package/sdk-core/core/src/ephemeral_server/mod.rs +5 -3
  27. package/sdk-core/core/src/protosext/mod.rs +3 -0
  28. package/sdk-core/core/src/telemetry/mod.rs +0 -8
  29. package/sdk-core/core/src/telemetry/otel.rs +7 -3
  30. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +11 -0
  31. package/sdk-core/core/src/worker/activities.rs +1 -1
  32. package/sdk-core/core/src/worker/mod.rs +6 -6
  33. package/sdk-core/core/src/worker/slot_provider.rs +4 -3
  34. package/sdk-core/core/src/worker/tuner/resource_based.rs +1 -1
  35. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +28 -2
  36. package/sdk-core/core/src/worker/workflow/history_update.rs +2 -2
  37. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +8 -5
  38. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -1
  39. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -1
  40. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +7 -7
  41. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +10 -15
  42. package/sdk-core/core/src/worker/workflow/machines/mod.rs +1 -1
  43. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +3 -2
  44. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -1
  45. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +4 -4
  46. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +30 -20
  47. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +2 -2
  48. package/sdk-core/core/src/worker/workflow/managed_run.rs +20 -4
  49. package/sdk-core/core/src/worker/workflow/mod.rs +33 -29
  50. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +2 -2
  51. package/sdk-core/core-api/src/telemetry.rs +1 -0
  52. package/sdk-core/docker/docker-compose-telem.yaml +4 -4
  53. package/sdk-core/etc/otel-collector-config.yaml +12 -9
  54. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +2 -2
  55. package/sdk-core/sdk/src/lib.rs +30 -3
  56. package/sdk-core/sdk/src/workflow_context.rs +15 -2
  57. package/sdk-core/sdk/src/workflow_future.rs +28 -8
  58. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +31 -12
  59. package/sdk-core/sdk-core-protos/src/lib.rs +104 -63
  60. package/sdk-core/test-utils/src/lib.rs +4 -3
  61. package/sdk-core/tests/integ_tests/client_tests.rs +36 -7
  62. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -1
  63. package/sdk-core/tests/integ_tests/metrics_tests.rs +50 -4
  64. package/sdk-core/tests/integ_tests/queries_tests.rs +95 -62
  65. package/sdk-core/tests/integ_tests/update_tests.rs +16 -9
  66. package/sdk-core/tests/integ_tests/visibility_tests.rs +1 -1
  67. package/sdk-core/tests/integ_tests/worker_tests.rs +82 -1
  68. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +46 -8
  69. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +81 -2
  70. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +139 -4
  71. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +43 -28
  72. package/sdk-core/tests/integ_tests/workflow_tests.rs +2 -1
  73. package/sdk-core/tests/main.rs +28 -19
  74. package/sdk-core/tests/runner.rs +7 -2
  75. package/ts/index.ts +3 -0
@@ -340,7 +340,7 @@ impl StateMachineDefinition {
340
340
  let state_variants = states.iter().map(|s| {
341
341
  let statestr = s.to_string();
342
342
  quote! {
343
- #[display(fmt=#statestr)]
343
+ #[display(#statestr)]
344
344
  #s(#s)
345
345
  }
346
346
  });
@@ -397,7 +397,7 @@ impl StateMachineDefinition {
397
397
  .map(|v| {
398
398
  let vname = v.ident.to_string();
399
399
  quote! {
400
- #[display(fmt=#vname)]
400
+ #[display(#vname)]
401
401
  #v
402
402
  }
403
403
  })
@@ -97,6 +97,7 @@ use temporal_sdk_core_protos::{
97
97
  },
98
98
  temporal::api::{
99
99
  common::v1::Payload,
100
+ enums::v1::WorkflowTaskFailedCause,
100
101
  failure::v1::{failure, Failure},
101
102
  },
102
103
  TaskToken,
@@ -252,7 +253,7 @@ impl Worker {
252
253
  let wf_half = &*wf_half;
253
254
  async move {
254
255
  join_handle.await??;
255
- info!(run_id=%run_id, "Removing workflow from cache");
256
+ debug!(run_id=%run_id, "Removing workflow from cache");
256
257
  wf_half.workflows.borrow_mut().remove(&run_id);
257
258
  Ok(())
258
259
  }
@@ -395,16 +396,24 @@ impl WorkflowHalf {
395
396
  let mut res = None;
396
397
  let run_id = activation.run_id.clone();
397
398
 
398
- // If the activation is to start a workflow, create a new workflow driver for it,
399
+ // If the activation is to init a workflow, create a new workflow driver for it,
399
400
  // using the function associated with that workflow id
400
401
  if let Some(sw) = activation.jobs.iter().find_map(|j| match j.variant {
401
- Some(Variant::StartWorkflow(ref sw)) => Some(sw),
402
+ Some(Variant::InitializeWorkflow(ref sw)) => Some(sw),
402
403
  _ => None,
403
404
  }) {
404
405
  let workflow_type = &sw.workflow_type;
405
406
  let wf_fns_borrow = self.workflow_fns.borrow();
406
407
  let Some(wf_function) = wf_fns_borrow.get(workflow_type) else {
407
408
  warn!("Workflow type {workflow_type} not found");
409
+
410
+ completions_tx
411
+ .send(WorkflowActivationCompletion::fail(
412
+ run_id,
413
+ format!("Workflow type {workflow_type} not found").into(),
414
+ Some(WorkflowTaskFailedCause::WorkflowWorkerUnhandledFailure),
415
+ ))
416
+ .expect("Completion channel intact");
408
417
  return Ok(None);
409
418
  };
410
419
 
@@ -445,6 +454,24 @@ impl WorkflowHalf {
445
454
  .send(activation)
446
455
  .expect("Workflow should exist if we're sending it an activation");
447
456
  } else {
457
+ // When we failed to start a workflow, we never inserted it into the cache.
458
+ // But core sends us a `RemoveFromCache` job when we mark the StartWorkflow workflow activation
459
+ // as a failure, which we need to complete.
460
+ // Other SDKs add the workflow to the cache even when the workflow type is unknown/not found.
461
+ // To circumvent this, we simply mark any RemoveFromCache job for workflows that are not in the cache as complete.
462
+ if activation.jobs.len() == 1
463
+ && matches!(
464
+ activation.jobs.first().map(|j| &j.variant),
465
+ Some(Some(Variant::RemoveFromCache(_)))
466
+ )
467
+ {
468
+ completions_tx
469
+ .send(WorkflowActivationCompletion::from_cmds(run_id, vec![]))
470
+ .expect("Completion channel intact");
471
+ return Ok(None);
472
+ }
473
+
474
+ // In all other cases, we want to panic as the runtime could be in an inconsistent state at this point.
448
475
  bail!(
449
476
  "Got activation {:?} for unknown workflow {}",
450
477
  activation,
@@ -13,11 +13,12 @@ use crate::{
13
13
  };
14
14
  use crossbeam_channel::{Receiver, Sender};
15
15
  use futures::{task::Context, FutureExt, Stream, StreamExt};
16
- use parking_lot::RwLock;
16
+ use parking_lot::{RwLock, RwLockReadGuard};
17
17
  use std::{
18
18
  collections::HashMap,
19
19
  future::Future,
20
20
  marker::PhantomData,
21
+ ops::Deref,
21
22
  pin::Pin,
22
23
  sync::{
23
24
  atomic::{AtomicBool, Ordering},
@@ -40,7 +41,7 @@ use temporal_sdk_core_protos::{
40
41
  SignalExternalWorkflowExecution, StartTimer, UpsertWorkflowSearchAttributes,
41
42
  },
42
43
  },
43
- temporal::api::common::v1::{Memo, Payload},
44
+ temporal::api::common::v1::{Memo, Payload, SearchAttributes},
44
45
  };
45
46
  use tokio::sync::{mpsc, oneshot, watch};
46
47
  use tokio_stream::wrappers::UnboundedReceiverStream;
@@ -123,6 +124,16 @@ impl WfContext {
123
124
  self.shared.read().current_build_id.clone()
124
125
  }
125
126
 
127
+ /// Return current values for workflow search attributes
128
+ pub fn search_attributes(&self) -> impl Deref<Target = SearchAttributes> + '_ {
129
+ RwLockReadGuard::map(self.shared.read(), |s| &s.search_attributes)
130
+ }
131
+
132
+ /// Return the workflow's randomness seed
133
+ pub fn random_seed(&self) -> u64 {
134
+ self.shared.read().random_seed
135
+ }
136
+
126
137
  /// A future that resolves if/when the workflow is cancelled
127
138
  pub async fn cancelled(&self) {
128
139
  if *self.am_cancelled.borrow() {
@@ -412,6 +423,8 @@ pub(crate) struct WfContextSharedData {
412
423
  pub(crate) wf_time: Option<SystemTime>,
413
424
  pub(crate) history_length: u32,
414
425
  pub(crate) current_build_id: Option<String>,
426
+ pub(crate) search_attributes: SearchAttributes,
427
+ pub(crate) random_seed: u64,
415
428
  }
416
429
 
417
430
  /// Helper Wrapper that can drain the channel into a Vec<SignalData> in a blocking way. Useful
@@ -145,7 +145,11 @@ impl WorkflowFuture {
145
145
  fn fail_wft(&self, run_id: String, fail: Error) {
146
146
  warn!("Workflow task failed for {}: {}", run_id, fail);
147
147
  self.outgoing_completions
148
- .send(WorkflowActivationCompletion::fail(run_id, fail.into()))
148
+ .send(WorkflowActivationCompletion::fail(
149
+ run_id,
150
+ fail.into(),
151
+ None,
152
+ ))
149
153
  .expect("Completion channel intact");
150
154
  }
151
155
 
@@ -171,13 +175,14 @@ impl WorkflowFuture {
171
175
  ) -> Result<bool, Error> {
172
176
  if let Some(v) = variant {
173
177
  match v {
174
- Variant::StartWorkflow(_) => {
175
- // TODO: Can assign randomness seed whenever needed
178
+ Variant::InitializeWorkflow(_) => {
179
+ // Don't do anything in here. Init workflow is looked at earlier, before
180
+ // jobs are handled, and may have information taken out of it to avoid clones.
176
181
  }
177
182
  Variant::FireTimer(FireTimer { seq }) => {
178
183
  self.unblock(UnblockEvent::Timer(seq, TimerResult::Fired))?
179
184
  }
180
- Variant::ResolveActivity(ResolveActivity { seq, result }) => {
185
+ Variant::ResolveActivity(ResolveActivity { seq, result, .. }) => {
181
186
  self.unblock(UnblockEvent::Activity(
182
187
  seq,
183
188
  Box::new(result.context("Activity must have result")?),
@@ -196,7 +201,9 @@ impl WorkflowFuture {
196
201
  seq,
197
202
  Box::new(result.context("Child Workflow execution must have a result")?),
198
203
  ))?,
199
- Variant::UpdateRandomSeed(_) => (),
204
+ Variant::UpdateRandomSeed(rs) => {
205
+ self.wf_ctx.shared.write().random_seed = rs.randomness_seed;
206
+ }
200
207
  Variant::QueryWorkflow(q) => {
201
208
  error!(
202
209
  "Queries are not implemented in the Rust SDK. Got query '{}'",
@@ -307,7 +314,7 @@ impl Future for WorkflowFuture {
307
314
  fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
308
315
  'activations: loop {
309
316
  // WF must always receive an activation first before responding with commands
310
- let activation = match self.incoming_activations.poll_recv(cx) {
317
+ let mut activation = match self.incoming_activations.poll_recv(cx) {
311
318
  Poll::Ready(a) => match a {
312
319
  Some(act) => act,
313
320
  None => {
@@ -335,16 +342,28 @@ impl Future for WorkflowFuture {
335
342
 
336
343
  let mut die_of_eviction_when_done = false;
337
344
  let mut activation_cmds = vec![];
345
+ // Assign initial state from start workflow job
346
+ if let Some(start_info) = activation.jobs.iter_mut().find_map(|j| {
347
+ if let Some(Variant::InitializeWorkflow(s)) = j.variant.as_mut() {
348
+ Some(s)
349
+ } else {
350
+ None
351
+ }
352
+ }) {
353
+ let mut wlock = self.wf_ctx.shared.write();
354
+ wlock.random_seed = start_info.randomness_seed;
355
+ wlock.search_attributes = start_info.search_attributes.take().unwrap_or_default();
356
+ };
338
357
  // Lame hack to avoid hitting "unregistered" update handlers in a situation where
339
358
  // the history has no commands until an update is accepted. Will go away w/ SDK redesign
340
359
  if activation
341
360
  .jobs
342
361
  .iter()
343
- .any(|j| matches!(j.variant, Some(Variant::StartWorkflow(_))))
362
+ .any(|j| matches!(j.variant, Some(Variant::InitializeWorkflow(_))))
344
363
  && activation.jobs.iter().all(|j| {
345
364
  matches!(
346
365
  j.variant,
347
- Some(Variant::StartWorkflow(_) | Variant::DoUpdate(_))
366
+ Some(Variant::InitializeWorkflow(_) | Variant::DoUpdate(_))
348
367
  )
349
368
  })
350
369
  {
@@ -443,6 +462,7 @@ impl WorkflowFuture {
443
462
  message: errmsg,
444
463
  ..Default::default()
445
464
  },
465
+ None,
446
466
  ))
447
467
  .expect("Completion channel intact");
448
468
  // Loop back up because we're about to get evicted
@@ -23,22 +23,38 @@ import "temporal/sdk/core/common/common.proto";
23
23
  // ## Job ordering guarantees and semantics
24
24
  //
25
25
  // Core will, by default, order jobs within the activation as follows:
26
- // `patches -> signals/updates -> other -> queries -> evictions`
26
+ // 1. init workflow
27
+ // 2. patches
28
+ // 3. random-seed-updates
29
+ // 4. signals/updates
30
+ // 5. all others
31
+ // 6. local activity resolutions
32
+ // 7. queries
33
+ // 8. evictions
27
34
  //
28
35
  // This is because:
29
36
  // * Patches are expected to apply to the entire activation
30
37
  // * Signal and update handlers should be invoked before workflow routines are iterated. That is to
31
38
  // say before the users' main workflow function and anything spawned by it is allowed to continue.
39
+ // * Local activities resolutions go after other normal jobs because while *not* replaying, they
40
+ // will always take longer than anything else that produces an immediate job (which is
41
+ // effectively instant). When *replaying* we need to scan ahead for LA markers so that we can
42
+ // resolve them in the same activation that they completed in when not replaying. However, doing
43
+ // so would, by default, put those resolutions *before* any other immediate jobs that happened
44
+ // in that same activation (prime example: cancelling not-wait-for-cancel activities). So, we do
45
+ // this to ensure the LA resolution happens after that cancel (or whatever else it may be) as it
46
+ // normally would have when executing.
32
47
  // * Queries always go last (and, in fact, always come in their own activation)
33
48
  // * Evictions also always come in their own activation
34
49
  //
35
- // The downside of this reordering is that a signal or update handler may not observe that some
36
- // other event had already happened (ex: an activity completed) when it is first invoked, though it
37
- // will subsequently when workflow routines are driven. Core only does this reordering to make life
38
- // easier for languages that cannot explicitly control when workflow routines are iterated.
39
- // Languages that can explicitly control such iteration should prefer to apply all the jobs to state
40
- // (by resolving promises/futures, invoking handlers, etc as they iterate over the jobs) and then
41
- // only *after* that is done, drive the workflow routines.
50
+ // Core does this reordering to ensure that langs observe jobs in the same order during replay as
51
+ // they would have during execution. However, in principle, this ordering is not necessary
52
+ // (excepting queries/evictions, which definitely must come last) if lang layers apply all jobs to
53
+ // state *first* (by resolving promises/futures, marking handlers to be invoked, etc as they iterate
54
+ // over the jobs) and then only *after* that is done, drive coroutines/threads/whatever. If
55
+ // execution works this way, then determinism is only impacted by the order routines are driven in
56
+ // (which must be stable based on lang implementation or convention), rather than the order jobs are
57
+ // processed.
42
58
  //
43
59
  // ## Evictions
44
60
  //
@@ -74,8 +90,8 @@ message WorkflowActivation {
74
90
 
75
91
  message WorkflowActivationJob {
76
92
  oneof variant {
77
- // Begin a workflow for the first time
78
- StartWorkflow start_workflow = 1;
93
+ // A workflow is starting, record all of the information from its start event
94
+ InitializeWorkflow initialize_workflow = 1;
79
95
  // A timer has fired, allowing whatever was waiting on it (if anything) to proceed
80
96
  FireTimer fire_timer = 2;
81
97
  // Workflow was reset. The randomness seed must be updated.
@@ -110,8 +126,8 @@ message WorkflowActivationJob {
110
126
  }
111
127
  }
112
128
 
113
- // Start a new workflow
114
- message StartWorkflow {
129
+ // Initialize a new workflow
130
+ message InitializeWorkflow {
115
131
  // The identifier the lang-specific sdk uses to execute workflow code
116
132
  string workflow_type = 1;
117
133
  // The workflow id used on the temporal server
@@ -175,6 +191,9 @@ message ResolveActivity {
175
191
  // Sequence number as provided by lang in the corresponding ScheduleActivity command
176
192
  uint32 seq = 1;
177
193
  activity_result.ActivityResolution result = 2;
194
+ // Set to true if the resolution is for a local activity. This is used internally by Core and
195
+ // lang does not need to care about it.
196
+ bool is_local = 3;
178
197
  }
179
198
 
180
199
  // Notify a workflow that a start child workflow execution request has succeeded, failed or was
@@ -436,8 +436,10 @@ pub mod coresdk {
436
436
  pub mod workflow_activation {
437
437
  use crate::{
438
438
  coresdk::{
439
+ activity_result::{activity_resolution, ActivityResolution},
439
440
  common::NamespacedWorkflowExecution,
440
- workflow_activation::remove_from_cache::EvictionReason, FromPayloadsExt,
441
+ workflow_activation::remove_from_cache::EvictionReason,
442
+ FromPayloadsExt,
441
443
  },
442
444
  temporal::api::{
443
445
  enums::v1::WorkflowTaskFailedCause,
@@ -511,6 +513,12 @@ pub mod coresdk {
511
513
  }
512
514
  }
513
515
 
516
+ impl workflow_activation_job::Variant {
517
+ pub fn is_local_activity_resolution(&self) -> bool {
518
+ matches!(self, workflow_activation_job::Variant::ResolveActivity(ra) if ra.is_local)
519
+ }
520
+ }
521
+
514
522
  impl Display for EvictionReason {
515
523
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
516
524
  write!(f, "{self:?}")
@@ -558,8 +566,8 @@ pub mod coresdk {
558
566
  impl Display for workflow_activation_job::Variant {
559
567
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
560
568
  match self {
561
- workflow_activation_job::Variant::StartWorkflow(_) => {
562
- write!(f, "StartWorkflow")
569
+ workflow_activation_job::Variant::InitializeWorkflow(_) => {
570
+ write!(f, "InitializeWorkflow")
563
571
  }
564
572
  workflow_activation_job::Variant::FireTimer(t) => {
565
573
  write!(f, "FireTimer({})", t.seq)
@@ -577,7 +585,14 @@ pub mod coresdk {
577
585
  write!(f, "SignalWorkflow")
578
586
  }
579
587
  workflow_activation_job::Variant::ResolveActivity(r) => {
580
- write!(f, "ResolveActivity({})", r.seq)
588
+ write!(
589
+ f,
590
+ "ResolveActivity({}, {})",
591
+ r.seq,
592
+ r.result
593
+ .as_ref()
594
+ .unwrap_or_else(|| &ActivityResolution { status: None })
595
+ )
581
596
  }
582
597
  workflow_activation_job::Variant::NotifyHasPatch(_) => {
583
598
  write!(f, "NotifyHasPatch")
@@ -604,6 +619,28 @@ pub mod coresdk {
604
619
  }
605
620
  }
606
621
 
622
+ impl Display for ActivityResolution {
623
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
624
+ match self.status {
625
+ None => {
626
+ write!(f, "None")
627
+ }
628
+ Some(activity_resolution::Status::Failed(_)) => {
629
+ write!(f, "Failed")
630
+ }
631
+ Some(activity_resolution::Status::Completed(_)) => {
632
+ write!(f, "Completed")
633
+ }
634
+ Some(activity_resolution::Status::Cancelled(_)) => {
635
+ write!(f, "Cancelled")
636
+ }
637
+ Some(activity_resolution::Status::Backoff(_)) => {
638
+ write!(f, "Backoff")
639
+ }
640
+ }
641
+ }
642
+ }
643
+
607
644
  impl Display for QueryWorkflow {
608
645
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
609
646
  write!(
@@ -631,14 +668,14 @@ pub mod coresdk {
631
668
  }
632
669
  }
633
670
 
634
- /// Create a [StartWorkflow] job from corresponding event attributes
671
+ /// Create a [InitializeWorkflow] job from corresponding event attributes
635
672
  pub fn start_workflow_from_attribs(
636
673
  attrs: WorkflowExecutionStartedEventAttributes,
637
674
  workflow_id: String,
638
675
  randomness_seed: u64,
639
676
  start_time: Timestamp,
640
- ) -> StartWorkflow {
641
- StartWorkflow {
677
+ ) -> InitializeWorkflow {
678
+ InitializeWorkflow {
642
679
  workflow_type: attrs.workflow_type.map(|wt| wt.name).unwrap_or_default(),
643
680
  workflow_id,
644
681
  arguments: Vec::from_payloads(attrs.input),
@@ -950,13 +987,17 @@ pub mod coresdk {
950
987
  }
951
988
  }
952
989
 
953
- pub fn fail(run_id: impl Into<String>, failure: Failure) -> Self {
990
+ pub fn fail(
991
+ run_id: impl Into<String>,
992
+ failure: Failure,
993
+ cause: Option<WorkflowTaskFailedCause>,
994
+ ) -> Self {
954
995
  Self {
955
996
  run_id: run_id.into(),
956
997
  status: Some(workflow_activation_completion::Status::Failed(
957
998
  workflow_completion::Failure {
958
999
  failure: Some(failure),
959
- force_cause: WorkflowTaskFailedCause::Unspecified as i32,
1000
+ force_cause: cause.unwrap_or(WorkflowTaskFailedCause::Unspecified) as i32,
960
1001
  },
961
1002
  )),
962
1003
  }
@@ -1959,60 +2000,60 @@ pub mod temporal {
1959
2000
  pub fn event_type(&self) -> EventType {
1960
2001
  // I just absolutely _love_ this
1961
2002
  match self {
1962
- Attributes::WorkflowExecutionStartedEventAttributes(_) => {EventType::WorkflowExecutionStarted}
1963
- Attributes::WorkflowExecutionCompletedEventAttributes(_) => {EventType::WorkflowExecutionCompleted}
1964
- Attributes::WorkflowExecutionFailedEventAttributes(_) => {EventType::WorkflowExecutionFailed}
1965
- Attributes::WorkflowExecutionTimedOutEventAttributes(_) => {EventType::WorkflowExecutionTimedOut}
1966
- Attributes::WorkflowTaskScheduledEventAttributes(_) => {EventType::WorkflowTaskScheduled}
1967
- Attributes::WorkflowTaskStartedEventAttributes(_) => {EventType::WorkflowTaskStarted}
1968
- Attributes::WorkflowTaskCompletedEventAttributes(_) => {EventType::WorkflowTaskCompleted}
1969
- Attributes::WorkflowTaskTimedOutEventAttributes(_) => {EventType::WorkflowTaskTimedOut}
1970
- Attributes::WorkflowTaskFailedEventAttributes(_) => {EventType::WorkflowTaskFailed}
1971
- Attributes::ActivityTaskScheduledEventAttributes(_) => {EventType::ActivityTaskScheduled}
1972
- Attributes::ActivityTaskStartedEventAttributes(_) => {EventType::ActivityTaskStarted}
1973
- Attributes::ActivityTaskCompletedEventAttributes(_) => {EventType::ActivityTaskCompleted}
1974
- Attributes::ActivityTaskFailedEventAttributes(_) => {EventType::ActivityTaskFailed}
1975
- Attributes::ActivityTaskTimedOutEventAttributes(_) => {EventType::ActivityTaskTimedOut}
1976
- Attributes::TimerStartedEventAttributes(_) => {EventType::TimerStarted}
1977
- Attributes::TimerFiredEventAttributes(_) => {EventType::TimerFired}
1978
- Attributes::ActivityTaskCancelRequestedEventAttributes(_) => {EventType::ActivityTaskCancelRequested}
1979
- Attributes::ActivityTaskCanceledEventAttributes(_) => {EventType::ActivityTaskCanceled}
1980
- Attributes::TimerCanceledEventAttributes(_) => {EventType::TimerCanceled}
1981
- Attributes::MarkerRecordedEventAttributes(_) => {EventType::MarkerRecorded}
1982
- Attributes::WorkflowExecutionSignaledEventAttributes(_) => {EventType::WorkflowExecutionSignaled}
1983
- Attributes::WorkflowExecutionTerminatedEventAttributes(_) => {EventType::WorkflowExecutionTerminated}
1984
- Attributes::WorkflowExecutionCancelRequestedEventAttributes(_) => {EventType::WorkflowExecutionCancelRequested}
1985
- Attributes::WorkflowExecutionCanceledEventAttributes(_) => {EventType::WorkflowExecutionCanceled}
1986
- Attributes::RequestCancelExternalWorkflowExecutionInitiatedEventAttributes(_) => {EventType::RequestCancelExternalWorkflowExecutionInitiated}
1987
- Attributes::RequestCancelExternalWorkflowExecutionFailedEventAttributes(_) => {EventType::RequestCancelExternalWorkflowExecutionFailed}
1988
- Attributes::ExternalWorkflowExecutionCancelRequestedEventAttributes(_) => {EventType::ExternalWorkflowExecutionCancelRequested}
1989
- Attributes::WorkflowExecutionContinuedAsNewEventAttributes(_) => {EventType::WorkflowExecutionContinuedAsNew}
1990
- Attributes::StartChildWorkflowExecutionInitiatedEventAttributes(_) => {EventType::StartChildWorkflowExecutionInitiated}
1991
- Attributes::StartChildWorkflowExecutionFailedEventAttributes(_) => {EventType::StartChildWorkflowExecutionFailed}
1992
- Attributes::ChildWorkflowExecutionStartedEventAttributes(_) => {EventType::ChildWorkflowExecutionStarted}
1993
- Attributes::ChildWorkflowExecutionCompletedEventAttributes(_) => {EventType::ChildWorkflowExecutionCompleted}
1994
- Attributes::ChildWorkflowExecutionFailedEventAttributes(_) => {EventType::ChildWorkflowExecutionFailed}
1995
- Attributes::ChildWorkflowExecutionCanceledEventAttributes(_) => {EventType::ChildWorkflowExecutionCanceled}
1996
- Attributes::ChildWorkflowExecutionTimedOutEventAttributes(_) => {EventType::ChildWorkflowExecutionTimedOut}
1997
- Attributes::ChildWorkflowExecutionTerminatedEventAttributes(_) => {EventType::ChildWorkflowExecutionTerminated}
1998
- Attributes::SignalExternalWorkflowExecutionInitiatedEventAttributes(_) => {EventType::SignalExternalWorkflowExecutionInitiated}
1999
- Attributes::SignalExternalWorkflowExecutionFailedEventAttributes(_) => {EventType::SignalExternalWorkflowExecutionFailed}
2000
- Attributes::ExternalWorkflowExecutionSignaledEventAttributes(_) => {EventType::ExternalWorkflowExecutionSignaled}
2001
- Attributes::UpsertWorkflowSearchAttributesEventAttributes(_) => {EventType::UpsertWorkflowSearchAttributes}
2002
- Attributes::WorkflowExecutionUpdateAdmittedEventAttributes(_) => {EventType::WorkflowExecutionUpdateAdmitted}
2003
- Attributes::WorkflowExecutionUpdateRejectedEventAttributes(_) => {EventType::WorkflowExecutionUpdateRejected}
2004
- Attributes::WorkflowExecutionUpdateAcceptedEventAttributes(_) => {EventType::WorkflowExecutionUpdateAccepted}
2005
- Attributes::WorkflowExecutionUpdateCompletedEventAttributes(_) => {EventType::WorkflowExecutionUpdateCompleted}
2006
- Attributes::WorkflowPropertiesModifiedExternallyEventAttributes(_) => {EventType::WorkflowPropertiesModifiedExternally}
2007
- Attributes::ActivityPropertiesModifiedExternallyEventAttributes(_) => {EventType::ActivityPropertiesModifiedExternally}
2008
- Attributes::WorkflowPropertiesModifiedEventAttributes(_) => {EventType::WorkflowPropertiesModified}
2009
- Attributes::NexusOperationScheduledEventAttributes(_) => {EventType::NexusOperationScheduled}
2010
- Attributes::NexusOperationStartedEventAttributes(_) => {EventType::NexusOperationStarted}
2011
- Attributes::NexusOperationCompletedEventAttributes(_) => {EventType::NexusOperationCompleted}
2012
- Attributes::NexusOperationFailedEventAttributes(_) => {EventType::NexusOperationFailed}
2013
- Attributes::NexusOperationCanceledEventAttributes(_) => {EventType::NexusOperationCanceled}
2014
- Attributes::NexusOperationTimedOutEventAttributes(_) => {EventType::NexusOperationTimedOut}
2015
- Attributes::NexusOperationCancelRequestedEventAttributes(_) => {EventType::NexusOperationCancelRequested}
2003
+ Attributes::WorkflowExecutionStartedEventAttributes(_) => { EventType::WorkflowExecutionStarted }
2004
+ Attributes::WorkflowExecutionCompletedEventAttributes(_) => { EventType::WorkflowExecutionCompleted }
2005
+ Attributes::WorkflowExecutionFailedEventAttributes(_) => { EventType::WorkflowExecutionFailed }
2006
+ Attributes::WorkflowExecutionTimedOutEventAttributes(_) => { EventType::WorkflowExecutionTimedOut }
2007
+ Attributes::WorkflowTaskScheduledEventAttributes(_) => { EventType::WorkflowTaskScheduled }
2008
+ Attributes::WorkflowTaskStartedEventAttributes(_) => { EventType::WorkflowTaskStarted }
2009
+ Attributes::WorkflowTaskCompletedEventAttributes(_) => { EventType::WorkflowTaskCompleted }
2010
+ Attributes::WorkflowTaskTimedOutEventAttributes(_) => { EventType::WorkflowTaskTimedOut }
2011
+ Attributes::WorkflowTaskFailedEventAttributes(_) => { EventType::WorkflowTaskFailed }
2012
+ Attributes::ActivityTaskScheduledEventAttributes(_) => { EventType::ActivityTaskScheduled }
2013
+ Attributes::ActivityTaskStartedEventAttributes(_) => { EventType::ActivityTaskStarted }
2014
+ Attributes::ActivityTaskCompletedEventAttributes(_) => { EventType::ActivityTaskCompleted }
2015
+ Attributes::ActivityTaskFailedEventAttributes(_) => { EventType::ActivityTaskFailed }
2016
+ Attributes::ActivityTaskTimedOutEventAttributes(_) => { EventType::ActivityTaskTimedOut }
2017
+ Attributes::TimerStartedEventAttributes(_) => { EventType::TimerStarted }
2018
+ Attributes::TimerFiredEventAttributes(_) => { EventType::TimerFired }
2019
+ Attributes::ActivityTaskCancelRequestedEventAttributes(_) => { EventType::ActivityTaskCancelRequested }
2020
+ Attributes::ActivityTaskCanceledEventAttributes(_) => { EventType::ActivityTaskCanceled }
2021
+ Attributes::TimerCanceledEventAttributes(_) => { EventType::TimerCanceled }
2022
+ Attributes::MarkerRecordedEventAttributes(_) => { EventType::MarkerRecorded }
2023
+ Attributes::WorkflowExecutionSignaledEventAttributes(_) => { EventType::WorkflowExecutionSignaled }
2024
+ Attributes::WorkflowExecutionTerminatedEventAttributes(_) => { EventType::WorkflowExecutionTerminated }
2025
+ Attributes::WorkflowExecutionCancelRequestedEventAttributes(_) => { EventType::WorkflowExecutionCancelRequested }
2026
+ Attributes::WorkflowExecutionCanceledEventAttributes(_) => { EventType::WorkflowExecutionCanceled }
2027
+ Attributes::RequestCancelExternalWorkflowExecutionInitiatedEventAttributes(_) => { EventType::RequestCancelExternalWorkflowExecutionInitiated }
2028
+ Attributes::RequestCancelExternalWorkflowExecutionFailedEventAttributes(_) => { EventType::RequestCancelExternalWorkflowExecutionFailed }
2029
+ Attributes::ExternalWorkflowExecutionCancelRequestedEventAttributes(_) => { EventType::ExternalWorkflowExecutionCancelRequested }
2030
+ Attributes::WorkflowExecutionContinuedAsNewEventAttributes(_) => { EventType::WorkflowExecutionContinuedAsNew }
2031
+ Attributes::StartChildWorkflowExecutionInitiatedEventAttributes(_) => { EventType::StartChildWorkflowExecutionInitiated }
2032
+ Attributes::StartChildWorkflowExecutionFailedEventAttributes(_) => { EventType::StartChildWorkflowExecutionFailed }
2033
+ Attributes::ChildWorkflowExecutionStartedEventAttributes(_) => { EventType::ChildWorkflowExecutionStarted }
2034
+ Attributes::ChildWorkflowExecutionCompletedEventAttributes(_) => { EventType::ChildWorkflowExecutionCompleted }
2035
+ Attributes::ChildWorkflowExecutionFailedEventAttributes(_) => { EventType::ChildWorkflowExecutionFailed }
2036
+ Attributes::ChildWorkflowExecutionCanceledEventAttributes(_) => { EventType::ChildWorkflowExecutionCanceled }
2037
+ Attributes::ChildWorkflowExecutionTimedOutEventAttributes(_) => { EventType::ChildWorkflowExecutionTimedOut }
2038
+ Attributes::ChildWorkflowExecutionTerminatedEventAttributes(_) => { EventType::ChildWorkflowExecutionTerminated }
2039
+ Attributes::SignalExternalWorkflowExecutionInitiatedEventAttributes(_) => { EventType::SignalExternalWorkflowExecutionInitiated }
2040
+ Attributes::SignalExternalWorkflowExecutionFailedEventAttributes(_) => { EventType::SignalExternalWorkflowExecutionFailed }
2041
+ Attributes::ExternalWorkflowExecutionSignaledEventAttributes(_) => { EventType::ExternalWorkflowExecutionSignaled }
2042
+ Attributes::UpsertWorkflowSearchAttributesEventAttributes(_) => { EventType::UpsertWorkflowSearchAttributes }
2043
+ Attributes::WorkflowExecutionUpdateAdmittedEventAttributes(_) => { EventType::WorkflowExecutionUpdateAdmitted }
2044
+ Attributes::WorkflowExecutionUpdateRejectedEventAttributes(_) => { EventType::WorkflowExecutionUpdateRejected }
2045
+ Attributes::WorkflowExecutionUpdateAcceptedEventAttributes(_) => { EventType::WorkflowExecutionUpdateAccepted }
2046
+ Attributes::WorkflowExecutionUpdateCompletedEventAttributes(_) => { EventType::WorkflowExecutionUpdateCompleted }
2047
+ Attributes::WorkflowPropertiesModifiedExternallyEventAttributes(_) => { EventType::WorkflowPropertiesModifiedExternally }
2048
+ Attributes::ActivityPropertiesModifiedExternallyEventAttributes(_) => { EventType::ActivityPropertiesModifiedExternally }
2049
+ Attributes::WorkflowPropertiesModifiedEventAttributes(_) => { EventType::WorkflowPropertiesModified }
2050
+ Attributes::NexusOperationScheduledEventAttributes(_) => { EventType::NexusOperationScheduled }
2051
+ Attributes::NexusOperationStartedEventAttributes(_) => { EventType::NexusOperationStarted }
2052
+ Attributes::NexusOperationCompletedEventAttributes(_) => { EventType::NexusOperationCompleted }
2053
+ Attributes::NexusOperationFailedEventAttributes(_) => { EventType::NexusOperationFailed }
2054
+ Attributes::NexusOperationCanceledEventAttributes(_) => { EventType::NexusOperationCanceled }
2055
+ Attributes::NexusOperationTimedOutEventAttributes(_) => { EventType::NexusOperationTimedOut }
2056
+ Attributes::NexusOperationCancelRequestedEventAttributes(_) => { EventType::NexusOperationCancelRequested }
2016
2057
  }
2017
2058
  }
2018
2059
  }
@@ -73,11 +73,12 @@ pub const INTEG_USE_TLS_ENV_VAR: &str = "TEMPORAL_USE_TLS";
73
73
  pub const INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR: &str = "INTEG_TEMPORAL_DEV_SERVER_ON";
74
74
  /// This env var is set (to any value) if the test server is in use
75
75
  pub const INTEG_TEST_SERVER_USED_ENV_VAR: &str = "INTEG_TEST_SERVER_ON";
76
-
76
+ pub static SEARCH_ATTR_TXT: &str = "CustomTextField";
77
+ pub static SEARCH_ATTR_INT: &str = "CustomIntField";
77
78
  /// If set, turn export traces and metrics to the OTel collector at the given URL
78
- const OTEL_URL_ENV_VAR: &str = "TEMPORAL_INTEG_OTEL_URL";
79
+ pub const OTEL_URL_ENV_VAR: &str = "TEMPORAL_INTEG_OTEL_URL";
79
80
  /// If set, enable direct scraping of prom metrics on the specified port
80
- const PROM_ENABLE_ENV_VAR: &str = "TEMPORAL_INTEG_PROM_PORT";
81
+ pub const PROM_ENABLE_ENV_VAR: &str = "TEMPORAL_INTEG_PROM_PORT";
81
82
  #[macro_export]
82
83
  macro_rules! prost_dur {
83
84
  ($dur_call:ident $args:tt) => {
@@ -9,9 +9,12 @@ use std::{
9
9
  };
10
10
  use temporal_client::{Namespace, RetryConfig, WorkflowClientTrait, WorkflowService};
11
11
  use temporal_sdk_core_protos::temporal::api::{
12
- cloud::cloudservice::v1::GetNamespaceRequest, workflowservice::v1::DescribeNamespaceRequest,
12
+ cloud::cloudservice::v1::GetNamespaceRequest,
13
+ workflowservice::v1::{DescribeNamespaceRequest, GetWorkflowExecutionHistoryRequest},
14
+ };
15
+ use temporal_sdk_core_test_utils::{
16
+ get_integ_server_options, init_integ_telem, CoreWfStarter, NAMESPACE,
13
17
  };
14
- use temporal_sdk_core_test_utils::{get_integ_server_options, CoreWfStarter, NAMESPACE};
15
18
  use tokio::{
16
19
  net::TcpListener,
17
20
  sync::{mpsc::UnboundedSender, oneshot},
@@ -121,6 +124,7 @@ impl NamedService for GenericService {
121
124
 
122
125
  #[tokio::test]
123
126
  async fn timeouts_respected_one_call_fake_server() {
127
+ init_integ_telem();
124
128
  let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();
125
129
  let (header_tx, mut header_rx) = tokio::sync::mpsc::unbounded_channel();
126
130
 
@@ -155,8 +159,8 @@ async fn timeouts_respected_one_call_fake_server() {
155
159
  let mut client = opts.connect_no_namespace(None).await.unwrap();
156
160
 
157
161
  macro_rules! call_client {
158
- ($client:ident, $trx:ident, $client_fn:ident) => {
159
- let mut req = Request::new(Default::default());
162
+ ($client:ident, $trx:ident, $client_fn:ident, $msg:expr) => {
163
+ let mut req = Request::new($msg);
160
164
  req.set_timeout(Duration::from_millis(100));
161
165
  // Response is always error b/c empty body
162
166
  let _ = $client.$client_fn(req).await;
@@ -165,9 +169,34 @@ async fn timeouts_respected_one_call_fake_server() {
165
169
  };
166
170
  }
167
171
 
168
- call_client!(client, header_rx, get_workflow_execution_history);
169
- call_client!(client, header_rx, update_workflow_execution);
170
- call_client!(client, header_rx, poll_workflow_execution_update);
172
+ call_client!(
173
+ client,
174
+ header_rx,
175
+ get_workflow_execution_history,
176
+ Default::default()
177
+ );
178
+ call_client!(
179
+ client,
180
+ header_rx,
181
+ get_workflow_execution_history,
182
+ GetWorkflowExecutionHistoryRequest {
183
+ // Ensure these calls when done long-poll style still respect timeout
184
+ wait_new_event: true,
185
+ ..Default::default()
186
+ }
187
+ );
188
+ call_client!(
189
+ client,
190
+ header_rx,
191
+ update_workflow_execution,
192
+ Default::default()
193
+ );
194
+ call_client!(
195
+ client,
196
+ header_rx,
197
+ poll_workflow_execution_update,
198
+ Default::default()
199
+ );
171
200
 
172
201
  // Shutdown the server
173
202
  shutdown_tx.send(()).unwrap();
@@ -85,7 +85,7 @@ async fn activity_heartbeat() {
85
85
  variant: Some(workflow_activation_job::Variant::ResolveActivity(
86
86
  ResolveActivity {seq, result: Some(ActivityResolution {
87
87
  status: Some(act_res::Status::Completed(activity_result::Success{result: Some(r)})),
88
- ..})}
88
+ ..}),..}
89
89
  )),
90
90
  },
91
91
  ] => {