@temporalio/core-bridge 1.7.4 → 1.8.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 (90) hide show
  1. package/Cargo.lock +245 -247
  2. package/Cargo.toml +1 -1
  3. package/lib/errors.d.ts +9 -0
  4. package/lib/errors.js +13 -0
  5. package/lib/errors.js.map +1 -1
  6. package/lib/index.d.ts +19 -3
  7. package/lib/index.js.map +1 -1
  8. package/package.json +3 -3
  9. package/releases/aarch64-apple-darwin/index.node +0 -0
  10. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  11. package/releases/x86_64-apple-darwin/index.node +0 -0
  12. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  13. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  14. package/sdk-core/.github/workflows/heavy.yml +1 -1
  15. package/sdk-core/.github/workflows/semgrep.yml +25 -0
  16. package/sdk-core/README.md +2 -0
  17. package/sdk-core/cargo-tokio-console.sh +5 -0
  18. package/sdk-core/client/src/lib.rs +6 -41
  19. package/sdk-core/client/src/raw.rs +9 -0
  20. package/sdk-core/client/src/retry.rs +0 -16
  21. package/sdk-core/core/Cargo.toml +9 -5
  22. package/sdk-core/core/src/abstractions.rs +7 -75
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +16 -8
  24. package/sdk-core/core/src/core_tests/local_activities.rs +97 -5
  25. package/sdk-core/core/src/core_tests/mod.rs +1 -1
  26. package/sdk-core/core/src/core_tests/workers.rs +16 -16
  27. package/sdk-core/core/src/core_tests/workflow_tasks.rs +247 -28
  28. package/sdk-core/core/src/lib.rs +2 -3
  29. package/sdk-core/core/src/pollers/mod.rs +30 -3
  30. package/sdk-core/core/src/pollers/poll_buffer.rs +166 -77
  31. package/sdk-core/core/src/protosext/mod.rs +4 -8
  32. package/sdk-core/core/src/replay/mod.rs +1 -1
  33. package/sdk-core/core/src/telemetry/metrics.rs +9 -0
  34. package/sdk-core/core/src/telemetry/mod.rs +3 -0
  35. package/sdk-core/core/src/test_help/mod.rs +9 -16
  36. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +6 -31
  37. package/sdk-core/core/src/worker/activities/local_activities.rs +214 -110
  38. package/sdk-core/core/src/worker/activities.rs +72 -47
  39. package/sdk-core/core/src/worker/client/mocks.rs +1 -1
  40. package/sdk-core/core/src/worker/client.rs +45 -32
  41. package/sdk-core/core/src/worker/mod.rs +170 -122
  42. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +0 -4
  43. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -2
  44. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +9 -2
  45. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +6 -3
  46. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +74 -22
  47. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +3 -2
  48. package/sdk-core/core/src/worker/workflow/managed_run.rs +16 -3
  49. package/sdk-core/core/src/worker/workflow/mod.rs +13 -22
  50. package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -0
  51. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +4 -7
  52. package/sdk-core/core/src/worker/workflow/wft_poller.rs +38 -8
  53. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +1 -0
  54. package/sdk-core/core-api/src/worker.rs +43 -2
  55. package/sdk-core/protos/api_upstream/Makefile +1 -1
  56. package/sdk-core/protos/api_upstream/buf.yaml +1 -6
  57. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -0
  58. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +11 -0
  59. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
  60. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +1 -0
  61. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
  62. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +9 -0
  63. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +19 -0
  64. package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +5 -0
  65. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +36 -4
  66. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +24 -7
  67. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +4 -0
  68. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +76 -44
  69. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +23 -1
  70. package/sdk-core/protos/google/rpc/status.proto +52 -0
  71. package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +16 -0
  72. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
  73. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +6 -0
  74. package/sdk-core/sdk/src/lib.rs +31 -10
  75. package/sdk-core/sdk/src/workflow_future.rs +7 -5
  76. package/sdk-core/sdk-core-protos/src/history_builder.rs +2 -0
  77. package/sdk-core/sdk-core-protos/src/history_info.rs +1 -0
  78. package/sdk-core/sdk-core-protos/src/lib.rs +82 -73
  79. package/sdk-core/test-utils/Cargo.toml +1 -1
  80. package/sdk-core/test-utils/src/lib.rs +50 -37
  81. package/sdk-core/tests/integ_tests/metrics_tests.rs +143 -10
  82. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +26 -15
  83. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -1
  84. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +2 -2
  85. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +5 -1
  86. package/sdk-core/tests/integ_tests/workflow_tests.rs +1 -0
  87. package/src/conversions.rs +9 -2
  88. package/src/runtime.rs +5 -7
  89. package/ts/errors.ts +15 -0
  90. package/ts/index.ts +22 -4
@@ -65,6 +65,7 @@ use crate::{
65
65
  use anyhow::{anyhow, bail, Context};
66
66
  use app_data::AppData;
67
67
  use futures::{future::BoxFuture, FutureExt, StreamExt, TryFutureExt, TryStreamExt};
68
+ use serde::Serialize;
68
69
  use std::{
69
70
  any::{Any, TypeId},
70
71
  cell::RefCell,
@@ -147,7 +148,7 @@ struct WorkflowData {
147
148
  activation_chan: UnboundedSender<WorkflowActivation>,
148
149
  }
149
150
 
150
- struct WorkflowFutureHandle<F: Future<Output = Result<WorkflowResult<()>, JoinError>>> {
151
+ struct WorkflowFutureHandle<F: Future<Output = Result<WorkflowResult<Payload>, JoinError>>> {
151
152
  join_handle: F,
152
153
  run_id: String,
153
154
  }
@@ -193,10 +194,10 @@ impl Worker {
193
194
 
194
195
  /// Register a Workflow function to invoke when the Worker is asked to run a workflow of
195
196
  /// `workflow_type`
196
- pub fn register_wf<F: Into<WorkflowFunction>>(
197
+ pub fn register_wf(
197
198
  &mut self,
198
199
  workflow_type: impl Into<String>,
199
- wf_function: F,
200
+ wf_function: impl Into<WorkflowFunction>,
200
201
  ) {
201
202
  self.workflow_half
202
203
  .workflow_fns
@@ -383,7 +384,9 @@ impl WorkflowHalf {
383
384
  activation: WorkflowActivation,
384
385
  completions_tx: &UnboundedSender<WorkflowActivationCompletion>,
385
386
  ) -> Result<
386
- Option<WorkflowFutureHandle<impl Future<Output = Result<WorkflowResult<()>, JoinError>>>>,
387
+ Option<
388
+ WorkflowFutureHandle<impl Future<Output = Result<WorkflowResult<Payload>, JoinError>>>,
389
+ >,
387
390
  anyhow::Error,
388
391
  > {
389
392
  let mut res = None;
@@ -694,17 +697,21 @@ struct CommandSubscribeChildWorkflowCompletion {
694
697
  unblocker: oneshot::Sender<UnblockEvent>,
695
698
  }
696
699
 
697
- type WfFunc = dyn Fn(WfContext) -> BoxFuture<'static, WorkflowResult<()>> + Send + Sync + 'static;
700
+ type WfFunc = dyn Fn(WfContext) -> BoxFuture<'static, Result<WfExitValue<Payload>, anyhow::Error>>
701
+ + Send
702
+ + Sync
703
+ + 'static;
698
704
 
699
705
  /// The user's async function / workflow code
700
706
  pub struct WorkflowFunction {
701
707
  wf_func: Box<WfFunc>,
702
708
  }
703
709
 
704
- impl<F, Fut> From<F> for WorkflowFunction
710
+ impl<F, Fut, O> From<F> for WorkflowFunction
705
711
  where
706
712
  F: Fn(WfContext) -> Fut + Send + Sync + 'static,
707
- Fut: Future<Output = WorkflowResult<()>> + Send + 'static,
713
+ Fut: Future<Output = Result<WfExitValue<O>, anyhow::Error>> + Send + 'static,
714
+ O: Serialize + Debug,
708
715
  {
709
716
  fn from(wf_func: F) -> Self {
710
717
  Self::new(wf_func)
@@ -713,13 +720,27 @@ where
713
720
 
714
721
  impl WorkflowFunction {
715
722
  /// Build a workflow function from a closure or function pointer which accepts a [WfContext]
716
- pub fn new<F, Fut>(wf_func: F) -> Self
723
+ pub fn new<F, Fut, O>(f: F) -> Self
717
724
  where
718
725
  F: Fn(WfContext) -> Fut + Send + Sync + 'static,
719
- Fut: Future<Output = WorkflowResult<()>> + Send + 'static,
726
+ Fut: Future<Output = Result<WfExitValue<O>, anyhow::Error>> + Send + 'static,
727
+ O: Serialize + Debug,
720
728
  {
721
729
  Self {
722
- wf_func: Box::new(move |ctx: WfContext| wf_func(ctx).boxed()),
730
+ wf_func: Box::new(move |ctx: WfContext| {
731
+ (f)(ctx)
732
+ .map(|r| {
733
+ r.and_then(|r| {
734
+ Ok(match r {
735
+ WfExitValue::ContinueAsNew(b) => WfExitValue::ContinueAsNew(b),
736
+ WfExitValue::Cancelled => WfExitValue::Cancelled,
737
+ WfExitValue::Evicted => WfExitValue::Evicted,
738
+ WfExitValue::Normal(o) => WfExitValue::Normal(o.as_json_payload()?),
739
+ })
740
+ })
741
+ })
742
+ .boxed()
743
+ }),
723
744
  }
724
745
  }
725
746
  }
@@ -50,7 +50,7 @@ impl WorkflowFunction {
50
50
  args: Vec<Payload>,
51
51
  outgoing_completions: UnboundedSender<WorkflowActivationCompletion>,
52
52
  ) -> (
53
- impl Future<Output = WorkflowResult<()>>,
53
+ impl Future<Output = WorkflowResult<Payload>>,
54
54
  UnboundedSender<WorkflowActivation>,
55
55
  ) {
56
56
  let (cancel_tx, cancel_rx) = watch::channel(false);
@@ -93,7 +93,7 @@ enum SigChanOrBuffer {
93
93
 
94
94
  pub struct WorkflowFuture {
95
95
  /// Future produced by calling the workflow function
96
- inner: BoxFuture<'static, WorkflowResult<()>>,
96
+ inner: BoxFuture<'static, WorkflowResult<Payload>>,
97
97
  /// Commands produced inside user's wf code
98
98
  incoming_commands: Receiver<RustWfCmd>,
99
99
  /// Once blocked or the workflow has finished or errored out, the result is sent here
@@ -234,7 +234,7 @@ impl WorkflowFuture {
234
234
  }
235
235
 
236
236
  impl Future for WorkflowFuture {
237
- type Output = WorkflowResult<()>;
237
+ type Output = WorkflowResult<Payload>;
238
238
 
239
239
  fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
240
240
  'activations: loop {
@@ -443,10 +443,12 @@ impl Future for WorkflowFuture {
443
443
  match res {
444
444
  Ok(exit_val) => match exit_val {
445
445
  // TODO: Generic values
446
- WfExitValue::Normal(_) => {
446
+ WfExitValue::Normal(result) => {
447
447
  activation_cmds.push(
448
448
  workflow_command::Variant::CompleteWorkflowExecution(
449
- CompleteWorkflowExecution { result: None },
449
+ CompleteWorkflowExecution {
450
+ result: Some(result),
451
+ },
450
452
  ),
451
453
  );
452
454
  }
@@ -106,6 +106,7 @@ impl TestHistoryBuilder {
106
106
  pub fn add_workflow_task_started(&mut self) {
107
107
  self.final_workflow_task_started_event_id = self.add(WorkflowTaskStartedEventAttributes {
108
108
  scheduled_event_id: self.workflow_task_scheduled_event_id,
109
+ history_size_bytes: ((self.events.len() + 1) * 10) as i64,
109
110
  ..Default::default()
110
111
  });
111
112
  }
@@ -562,6 +563,7 @@ pub fn default_wes_attribs() -> WorkflowExecutionStartedEventAttributes {
562
563
  task_queue: Some(TaskQueue {
563
564
  name: "q".to_string(),
564
565
  kind: TaskQueueKind::Normal as i32,
566
+ normal_name: "".to_string(),
565
567
  }),
566
568
  ..Default::default()
567
569
  }
@@ -172,6 +172,7 @@ impl HistoryInfo {
172
172
  .name
173
173
  .clone(),
174
174
  kind: TaskQueueKind::Normal as i32,
175
+ normal_name: "".to_string(),
175
176
  }),
176
177
  previous_started_event_id: self.previous_started_event_id,
177
178
  started_event_id: self.workflow_task_started_event_id,
@@ -454,6 +454,8 @@ pub mod coresdk {
454
454
  }),
455
455
  )],
456
456
  available_internal_flags: vec![],
457
+ history_size_bytes: 0,
458
+ continue_as_new_suggested: false,
457
459
  }
458
460
  }
459
461
 
@@ -1500,53 +1502,57 @@ pub mod temporal {
1500
1502
  }
1501
1503
  }
1502
1504
 
1503
- impl From<workflow_commands::ScheduleActivity> for command::Attributes {
1504
- fn from(s: workflow_commands::ScheduleActivity) -> Self {
1505
- Self::ScheduleActivityTaskCommandAttributes(
1506
- ScheduleActivityTaskCommandAttributes {
1507
- activity_id: s.activity_id,
1508
- activity_type: Some(ActivityType {
1509
- name: s.activity_type,
1510
- }),
1511
- task_queue: Some(s.task_queue.into()),
1512
- header: Some(s.headers.into()),
1513
- input: s.arguments.into_payloads(),
1514
- schedule_to_close_timeout: s.schedule_to_close_timeout,
1515
- schedule_to_start_timeout: s.schedule_to_start_timeout,
1516
- start_to_close_timeout: s.start_to_close_timeout,
1517
- heartbeat_timeout: s.heartbeat_timeout,
1518
- retry_policy: s.retry_policy.map(Into::into),
1519
- request_eager_execution: !s.do_not_eagerly_execute,
1520
- },
1521
- )
1522
- }
1505
+ pub fn schedule_activity_cmd_to_api(
1506
+ s: workflow_commands::ScheduleActivity,
1507
+ use_compatible_version: bool,
1508
+ ) -> command::Attributes {
1509
+ command::Attributes::ScheduleActivityTaskCommandAttributes(
1510
+ ScheduleActivityTaskCommandAttributes {
1511
+ activity_id: s.activity_id,
1512
+ activity_type: Some(ActivityType {
1513
+ name: s.activity_type,
1514
+ }),
1515
+ task_queue: Some(s.task_queue.into()),
1516
+ header: Some(s.headers.into()),
1517
+ input: s.arguments.into_payloads(),
1518
+ schedule_to_close_timeout: s.schedule_to_close_timeout,
1519
+ schedule_to_start_timeout: s.schedule_to_start_timeout,
1520
+ start_to_close_timeout: s.start_to_close_timeout,
1521
+ heartbeat_timeout: s.heartbeat_timeout,
1522
+ retry_policy: s.retry_policy.map(Into::into),
1523
+ request_eager_execution: !s.do_not_eagerly_execute,
1524
+ use_compatible_version,
1525
+ },
1526
+ )
1523
1527
  }
1524
1528
 
1525
- impl From<workflow_commands::StartChildWorkflowExecution> for command::Attributes {
1526
- fn from(s: workflow_commands::StartChildWorkflowExecution) -> Self {
1527
- Self::StartChildWorkflowExecutionCommandAttributes(
1528
- StartChildWorkflowExecutionCommandAttributes {
1529
- workflow_id: s.workflow_id,
1530
- workflow_type: Some(WorkflowType {
1531
- name: s.workflow_type,
1532
- }),
1533
- control: "".into(),
1534
- namespace: s.namespace,
1535
- task_queue: Some(s.task_queue.into()),
1536
- header: Some(s.headers.into()),
1537
- memo: Some(s.memo.into()),
1538
- search_attributes: Some(s.search_attributes.into()),
1539
- input: s.input.into_payloads(),
1540
- workflow_id_reuse_policy: s.workflow_id_reuse_policy,
1541
- workflow_execution_timeout: s.workflow_execution_timeout,
1542
- workflow_run_timeout: s.workflow_run_timeout,
1543
- workflow_task_timeout: s.workflow_task_timeout,
1544
- retry_policy: s.retry_policy.map(Into::into),
1545
- cron_schedule: s.cron_schedule.clone(),
1546
- parent_close_policy: s.parent_close_policy,
1547
- },
1548
- )
1549
- }
1529
+ pub fn start_child_workflow_cmd_to_api(
1530
+ s: workflow_commands::StartChildWorkflowExecution,
1531
+ use_compatible_version: bool,
1532
+ ) -> command::Attributes {
1533
+ command::Attributes::StartChildWorkflowExecutionCommandAttributes(
1534
+ StartChildWorkflowExecutionCommandAttributes {
1535
+ workflow_id: s.workflow_id,
1536
+ workflow_type: Some(WorkflowType {
1537
+ name: s.workflow_type,
1538
+ }),
1539
+ control: "".into(),
1540
+ namespace: s.namespace,
1541
+ task_queue: Some(s.task_queue.into()),
1542
+ header: Some(s.headers.into()),
1543
+ memo: Some(s.memo.into()),
1544
+ search_attributes: Some(s.search_attributes.into()),
1545
+ input: s.input.into_payloads(),
1546
+ workflow_id_reuse_policy: s.workflow_id_reuse_policy,
1547
+ workflow_execution_timeout: s.workflow_execution_timeout,
1548
+ workflow_run_timeout: s.workflow_run_timeout,
1549
+ workflow_task_timeout: s.workflow_task_timeout,
1550
+ retry_policy: s.retry_policy.map(Into::into),
1551
+ cron_schedule: s.cron_schedule.clone(),
1552
+ parent_close_policy: s.parent_close_policy,
1553
+ use_compatible_version,
1554
+ },
1555
+ )
1550
1556
  }
1551
1557
 
1552
1558
  impl From<workflow_commands::CompleteWorkflowExecution> for command::Attributes {
@@ -1569,35 +1575,37 @@ pub mod temporal {
1569
1575
  }
1570
1576
  }
1571
1577
 
1572
- impl From<workflow_commands::ContinueAsNewWorkflowExecution> for command::Attributes {
1573
- fn from(c: workflow_commands::ContinueAsNewWorkflowExecution) -> Self {
1574
- Self::ContinueAsNewWorkflowExecutionCommandAttributes(
1575
- ContinueAsNewWorkflowExecutionCommandAttributes {
1576
- workflow_type: Some(c.workflow_type.into()),
1577
- task_queue: Some(c.task_queue.into()),
1578
- input: c.arguments.into_payloads(),
1579
- workflow_run_timeout: c.workflow_run_timeout,
1580
- workflow_task_timeout: c.workflow_task_timeout,
1581
- memo: if c.memo.is_empty() {
1582
- None
1583
- } else {
1584
- Some(c.memo.into())
1585
- },
1586
- header: if c.headers.is_empty() {
1587
- None
1588
- } else {
1589
- Some(c.headers.into())
1590
- },
1591
- retry_policy: c.retry_policy,
1592
- search_attributes: if c.search_attributes.is_empty() {
1593
- None
1594
- } else {
1595
- Some(c.search_attributes.into())
1596
- },
1597
- ..Default::default()
1578
+ pub fn continue_as_new_cmd_to_api(
1579
+ c: workflow_commands::ContinueAsNewWorkflowExecution,
1580
+ use_compatible_version: bool,
1581
+ ) -> command::Attributes {
1582
+ command::Attributes::ContinueAsNewWorkflowExecutionCommandAttributes(
1583
+ ContinueAsNewWorkflowExecutionCommandAttributes {
1584
+ workflow_type: Some(c.workflow_type.into()),
1585
+ task_queue: Some(c.task_queue.into()),
1586
+ input: c.arguments.into_payloads(),
1587
+ workflow_run_timeout: c.workflow_run_timeout,
1588
+ workflow_task_timeout: c.workflow_task_timeout,
1589
+ memo: if c.memo.is_empty() {
1590
+ None
1591
+ } else {
1592
+ Some(c.memo.into())
1598
1593
  },
1599
- )
1600
- }
1594
+ header: if c.headers.is_empty() {
1595
+ None
1596
+ } else {
1597
+ Some(c.headers.into())
1598
+ },
1599
+ retry_policy: c.retry_policy,
1600
+ search_attributes: if c.search_attributes.is_empty() {
1601
+ None
1602
+ } else {
1603
+ Some(c.search_attributes.into())
1604
+ },
1605
+ use_compatible_version,
1606
+ ..Default::default()
1607
+ },
1608
+ )
1601
1609
  }
1602
1610
 
1603
1611
  impl From<workflow_commands::CancelWorkflowExecution> for command::Attributes {
@@ -1971,6 +1979,7 @@ pub mod temporal {
1971
1979
  Self {
1972
1980
  name,
1973
1981
  kind: TaskQueueKind::Normal as i32,
1982
+ normal_name: "".to_string(),
1974
1983
  }
1975
1984
  }
1976
1985
  }
@@ -24,7 +24,7 @@ rmp-serde = "1.1"
24
24
  serde_json = "1.0"
25
25
  temporal-client = { path = "../client" }
26
26
  temporal-sdk = { path = "../sdk" }
27
- temporal-sdk-core = { path = "../core" }
27
+ temporal-sdk-core = { path = "../core", features = ["ephemeral-server"] }
28
28
  temporal-sdk-core-api = { path = "../core-api" }
29
29
  thiserror = "1.0"
30
30
  tokio = "1.1"
@@ -33,7 +33,7 @@ use temporal_sdk_core::{
33
33
  ephemeral_server::{EphemeralExe, EphemeralExeVersion},
34
34
  init_replay_worker, init_worker,
35
35
  replay::HistoryForReplay,
36
- ClientOptions, ClientOptionsBuilder, CoreRuntime, WorkerConfig, WorkerConfigBuilder,
36
+ ClientOptions, ClientOptionsBuilder, CoreRuntime, WorkerConfigBuilder,
37
37
  };
38
38
  use temporal_sdk_core_api::{
39
39
  errors::{PollActivityError, PollWfError},
@@ -61,6 +61,7 @@ pub const NAMESPACE: &str = "default";
61
61
  pub const TEST_Q: &str = "q";
62
62
  /// The env var used to specify where the integ tests should point
63
63
  pub const INTEG_SERVER_TARGET_ENV_VAR: &str = "TEMPORAL_SERVICE_ADDRESS";
64
+ pub const INTEG_NAMESPACE_ENV_VAR: &str = "TEMPORAL_NAMESPACE";
64
65
  pub const INTEG_USE_TLS_ENV_VAR: &str = "TEMPORAL_USE_TLS";
65
66
  /// This env var is set (to any value) if temporal CLI dev server is in use
66
67
  pub const INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR: &str = "INTEG_TEMPORAL_DEV_SERVER_ON";
@@ -153,10 +154,11 @@ pub fn init_integ_telem() {
153
154
  pub struct CoreWfStarter {
154
155
  /// Used for both the task queue and workflow id
155
156
  task_queue_name: String,
156
- pub worker_config: WorkerConfig,
157
+ pub worker_config: WorkerConfigBuilder,
157
158
  /// Options to use when starting workflow(s)
158
159
  pub workflow_options: WorkflowOptions,
159
160
  initted_worker: OnceCell<InitializedWorker>,
161
+ runtime_override: Option<CoreRuntime>,
160
162
  }
161
163
  struct InitializedWorker {
162
164
  worker: Arc<dyn CoreWorker>,
@@ -166,28 +168,36 @@ struct InitializedWorker {
166
168
  impl CoreWfStarter {
167
169
  pub fn new(test_name: &str) -> Self {
168
170
  init_integ_telem();
171
+ Self::_new(test_name, None)
172
+ }
173
+
174
+ pub fn new_with_runtime(test_name: &str, runtime: CoreRuntime) -> Self {
175
+ Self::_new(test_name, Some(runtime))
176
+ }
177
+
178
+ fn _new(test_name: &str, runtime_override: Option<CoreRuntime>) -> Self {
169
179
  let rand_bytes: Vec<u8> = rand::thread_rng().sample_iter(&Standard).take(6).collect();
170
180
  let task_q_salt = BASE64_STANDARD.encode(rand_bytes);
171
181
  let task_queue = format!("{test_name}_{task_q_salt}");
182
+ let mut worker_config = WorkerConfigBuilder::default();
183
+ worker_config
184
+ .namespace(env::var(INTEG_NAMESPACE_ENV_VAR).unwrap_or(NAMESPACE.to_string()))
185
+ .task_queue(task_queue.clone())
186
+ .worker_build_id("test_build_id")
187
+ .max_cached_workflows(1000_usize);
172
188
  Self {
173
- task_queue_name: task_queue.to_owned(),
174
- worker_config: WorkerConfigBuilder::default()
175
- .namespace(NAMESPACE)
176
- .task_queue(task_queue)
177
- .worker_build_id("test_build_id")
178
- .max_cached_workflows(1000_usize)
179
- .build()
180
- .unwrap(),
189
+ task_queue_name: task_queue,
190
+ worker_config,
181
191
  initted_worker: OnceCell::new(),
182
192
  workflow_options: Default::default(),
193
+ runtime_override,
183
194
  }
184
195
  }
185
196
 
186
197
  pub async fn worker(&mut self) -> TestWorker {
187
- let mut w = TestWorker::new(
188
- self.get_worker().await,
189
- self.worker_config.task_queue.clone(),
190
- );
198
+ let w = self.get_worker().await;
199
+ let tq = w.get_config().task_queue.clone();
200
+ let mut w = TestWorker::new(w, tq);
191
201
  w.client = Some(self.get_client().await);
192
202
 
193
203
  w
@@ -227,16 +237,14 @@ impl CoreWfStarter {
227
237
  }
228
238
 
229
239
  pub async fn start_wf_with_id(&self, workflow_id: String) -> String {
230
- self.initted_worker
231
- .get()
232
- .expect(
233
- "Worker must be initted before starting a workflow.\
240
+ let iw = self.initted_worker.get().expect(
241
+ "Worker must be initted before starting a workflow.\
234
242
  Tests must call `get_worker` first.",
235
- )
236
- .client
243
+ );
244
+ iw.client
237
245
  .start_workflow(
238
246
  vec![],
239
- self.worker_config.task_queue.clone(),
247
+ iw.worker.get_config().task_queue.clone(),
240
248
  workflow_id,
241
249
  self.task_queue_name.clone(),
242
250
  None,
@@ -273,7 +281,7 @@ impl CoreWfStarter {
273
281
  }
274
282
 
275
283
  pub fn get_task_queue(&self) -> &str {
276
- &self.worker_config.task_queue
284
+ &self.task_queue_name
277
285
  }
278
286
 
279
287
  pub fn get_wf_id(&self) -> &str {
@@ -281,60 +289,65 @@ impl CoreWfStarter {
281
289
  }
282
290
 
283
291
  pub fn max_cached_workflows(&mut self, num: usize) -> &mut Self {
284
- self.worker_config.max_cached_workflows = num;
292
+ self.worker_config.max_cached_workflows(num);
285
293
  self
286
294
  }
287
295
 
288
296
  pub fn max_wft(&mut self, max: usize) -> &mut Self {
289
- self.worker_config.max_outstanding_workflow_tasks = max;
297
+ self.worker_config.max_outstanding_workflow_tasks(max);
290
298
  self
291
299
  }
292
300
 
293
301
  pub fn max_at(&mut self, max: usize) -> &mut Self {
294
- self.worker_config.max_outstanding_activities = max;
302
+ self.worker_config.max_outstanding_activities(max);
295
303
  self
296
304
  }
297
305
 
298
306
  pub fn max_local_at(&mut self, max: usize) -> &mut Self {
299
- self.worker_config.max_outstanding_local_activities = max;
307
+ self.worker_config.max_outstanding_local_activities(max);
300
308
  self
301
309
  }
302
310
 
303
311
  pub fn max_at_polls(&mut self, max: usize) -> &mut Self {
304
- self.worker_config.max_concurrent_at_polls = max;
312
+ self.worker_config.max_concurrent_at_polls(max);
313
+
305
314
  self
306
315
  }
307
316
 
308
317
  pub fn no_remote_activities(&mut self) -> &mut Self {
309
- self.worker_config.no_remote_activities = true;
318
+ self.worker_config.no_remote_activities(true);
310
319
  self
311
320
  }
312
321
 
313
322
  pub fn enable_wf_state_input_recording(&mut self) -> &mut Self {
314
323
  let (ser_tx, ser_rx) = unbounded_channel();
315
- let worker_cfg_clone = self.worker_config.clone();
324
+ let worker_cfg_clone = self.worker_config.build().unwrap();
316
325
  tokio::spawn(async move {
317
326
  stream_to_file(&worker_cfg_clone, ser_rx).await.unwrap();
318
327
  });
319
- self.worker_config.wf_state_inputs = Some(ser_tx);
328
+ self.worker_config.wf_state_inputs(Some(ser_tx));
320
329
  self
321
330
  }
322
331
 
323
332
  async fn get_or_init(&mut self) -> &InitializedWorker {
324
333
  self.initted_worker
325
334
  .get_or_init(|| async {
335
+ let cfg = self
336
+ .worker_config
337
+ .build()
338
+ .expect("Worker config must be valid");
326
339
  let client = Arc::new(
327
340
  get_integ_server_options()
328
- .connect(self.worker_config.namespace.clone(), None, None)
341
+ .connect(cfg.namespace.clone(), None, None)
329
342
  .await
330
343
  .expect("Must connect"),
331
344
  );
332
- let worker = init_worker(
333
- INTEG_TESTS_RT.get().unwrap(),
334
- self.worker_config.clone(),
335
- client.clone(),
336
- )
337
- .expect("Worker inits cleanly");
345
+ let rt = if let Some(ref rto) = self.runtime_override {
346
+ rto
347
+ } else {
348
+ INTEG_TESTS_RT.get().unwrap()
349
+ };
350
+ let worker = init_worker(rt, cfg, client.clone()).expect("Worker inits cleanly");
338
351
  InitializedWorker {
339
352
  worker: Arc::new(worker),
340
353
  client,