@temporalio/core-bridge 1.5.2 → 1.7.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 (194) hide show
  1. package/Cargo.lock +304 -112
  2. package/lib/index.d.ts +8 -6
  3. package/lib/index.js.map +1 -1
  4. package/package.json +9 -4
  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/.buildkite/docker/Dockerfile +2 -2
  11. package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
  12. package/sdk-core/.buildkite/pipeline.yml +2 -4
  13. package/sdk-core/.cargo/config.toml +5 -2
  14. package/sdk-core/.github/workflows/heavy.yml +29 -0
  15. package/sdk-core/Cargo.toml +1 -1
  16. package/sdk-core/README.md +20 -10
  17. package/sdk-core/client/src/lib.rs +215 -39
  18. package/sdk-core/client/src/metrics.rs +17 -8
  19. package/sdk-core/client/src/raw.rs +4 -4
  20. package/sdk-core/client/src/retry.rs +32 -20
  21. package/sdk-core/core/Cargo.toml +25 -12
  22. package/sdk-core/core/src/abstractions/take_cell.rs +28 -0
  23. package/sdk-core/core/src/abstractions.rs +204 -14
  24. package/sdk-core/core/src/core_tests/activity_tasks.rs +143 -50
  25. package/sdk-core/core/src/core_tests/child_workflows.rs +6 -5
  26. package/sdk-core/core/src/core_tests/determinism.rs +165 -2
  27. package/sdk-core/core/src/core_tests/local_activities.rs +431 -43
  28. package/sdk-core/core/src/core_tests/queries.rs +34 -16
  29. package/sdk-core/core/src/core_tests/workers.rs +8 -5
  30. package/sdk-core/core/src/core_tests/workflow_tasks.rs +588 -55
  31. package/sdk-core/core/src/ephemeral_server/mod.rs +113 -12
  32. package/sdk-core/core/src/internal_flags.rs +155 -0
  33. package/sdk-core/core/src/lib.rs +16 -9
  34. package/sdk-core/core/src/protosext/mod.rs +1 -1
  35. package/sdk-core/core/src/replay/mod.rs +16 -27
  36. package/sdk-core/core/src/telemetry/log_export.rs +1 -1
  37. package/sdk-core/core/src/telemetry/metrics.rs +69 -35
  38. package/sdk-core/core/src/telemetry/mod.rs +60 -21
  39. package/sdk-core/core/src/telemetry/prometheus_server.rs +19 -13
  40. package/sdk-core/core/src/test_help/mod.rs +73 -14
  41. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +119 -160
  42. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  43. package/sdk-core/core/src/worker/activities/local_activities.rs +379 -129
  44. package/sdk-core/core/src/worker/activities.rs +350 -175
  45. package/sdk-core/core/src/worker/client/mocks.rs +22 -2
  46. package/sdk-core/core/src/worker/client.rs +18 -2
  47. package/sdk-core/core/src/worker/mod.rs +183 -64
  48. package/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  49. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  50. package/sdk-core/core/src/worker/workflow/history_update.rs +916 -277
  51. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +216 -183
  52. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +9 -12
  53. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +7 -9
  54. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +160 -87
  55. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +13 -14
  56. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +7 -9
  57. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +14 -17
  58. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +242 -110
  59. package/sdk-core/core/src/worker/workflow/machines/mod.rs +27 -19
  60. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +9 -11
  61. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +321 -206
  62. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +13 -18
  63. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +20 -29
  64. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  65. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +257 -51
  66. package/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
  67. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +310 -150
  68. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +17 -20
  69. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +31 -15
  70. package/sdk-core/core/src/worker/workflow/managed_run.rs +1052 -380
  71. package/sdk-core/core/src/worker/workflow/mod.rs +598 -390
  72. package/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  73. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +137 -0
  74. package/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  75. package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  76. package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  77. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +469 -718
  78. package/sdk-core/core-api/Cargo.toml +2 -1
  79. package/sdk-core/core-api/src/errors.rs +1 -34
  80. package/sdk-core/core-api/src/lib.rs +19 -9
  81. package/sdk-core/core-api/src/telemetry.rs +4 -6
  82. package/sdk-core/core-api/src/worker.rs +19 -1
  83. package/sdk-core/etc/deps.svg +115 -140
  84. package/sdk-core/etc/regen-depgraph.sh +5 -0
  85. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +86 -61
  86. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +29 -71
  87. package/sdk-core/histories/ends_empty_wft_complete.bin +0 -0
  88. package/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  89. package/sdk-core/histories/old_change_marker_format.bin +0 -0
  90. package/sdk-core/protos/api_upstream/.github/CODEOWNERS +2 -1
  91. package/sdk-core/protos/api_upstream/Makefile +6 -6
  92. package/sdk-core/protos/api_upstream/build/go.mod +7 -0
  93. package/sdk-core/protos/api_upstream/build/go.sum +5 -0
  94. package/sdk-core/protos/api_upstream/build/tools.go +29 -0
  95. package/sdk-core/protos/api_upstream/go.mod +6 -0
  96. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +9 -2
  97. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +7 -26
  98. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
  99. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  100. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +3 -7
  101. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  102. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +8 -8
  103. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +25 -2
  104. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  105. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  106. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  107. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  108. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  109. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +24 -19
  110. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  111. package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  112. package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  113. package/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  114. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +49 -26
  115. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +4 -2
  116. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +5 -2
  117. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
  118. package/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +57 -0
  119. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  120. package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  121. package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
  122. package/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  123. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
  124. package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +71 -6
  125. package/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  126. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -2
  127. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -28
  128. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +4 -4
  129. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +7 -8
  130. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +10 -7
  131. package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +19 -30
  132. package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  133. package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  134. package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +8 -0
  135. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +67 -60
  136. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +85 -84
  137. package/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +9 -3
  138. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  139. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  140. package/sdk-core/sdk/Cargo.toml +5 -4
  141. package/sdk-core/sdk/src/lib.rs +108 -26
  142. package/sdk-core/sdk/src/workflow_context/options.rs +7 -1
  143. package/sdk-core/sdk/src/workflow_context.rs +24 -17
  144. package/sdk-core/sdk/src/workflow_future.rs +16 -15
  145. package/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  146. package/sdk-core/sdk-core-protos/build.rs +36 -2
  147. package/sdk-core/sdk-core-protos/src/history_builder.rs +138 -106
  148. package/sdk-core/sdk-core-protos/src/history_info.rs +10 -1
  149. package/sdk-core/sdk-core-protos/src/lib.rs +272 -87
  150. package/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  151. package/sdk-core/test-utils/Cargo.toml +3 -1
  152. package/sdk-core/test-utils/src/canned_histories.rs +106 -296
  153. package/sdk-core/test-utils/src/histfetch.rs +1 -1
  154. package/sdk-core/test-utils/src/lib.rs +82 -23
  155. package/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  156. package/sdk-core/test-utils/src/workflows.rs +29 -0
  157. package/sdk-core/tests/fuzzy_workflow.rs +130 -0
  158. package/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  159. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  160. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +10 -5
  161. package/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
  162. package/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
  163. package/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  164. package/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  165. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +161 -72
  166. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  167. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  168. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +80 -3
  169. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  170. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  171. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +94 -200
  172. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +2 -4
  173. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +34 -28
  174. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +76 -7
  175. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  176. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  177. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  178. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  179. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +7 -8
  180. package/sdk-core/tests/integ_tests/workflow_tests.rs +13 -14
  181. package/sdk-core/tests/main.rs +3 -13
  182. package/sdk-core/tests/runner.rs +75 -36
  183. package/sdk-core/tests/wf_input_replay.rs +32 -0
  184. package/src/conversions.rs +14 -8
  185. package/src/runtime.rs +9 -8
  186. package/ts/index.ts +8 -6
  187. package/sdk-core/bridge-ffi/Cargo.toml +0 -24
  188. package/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  189. package/sdk-core/bridge-ffi/build.rs +0 -25
  190. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -224
  191. package/sdk-core/bridge-ffi/src/lib.rs +0 -746
  192. package/sdk-core/bridge-ffi/src/wrappers.rs +0 -221
  193. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  194. package/sdk-core/sdk/src/conversions.rs +0 -8
@@ -1,13 +1,35 @@
1
1
  use std::time::{SystemTime, UNIX_EPOCH};
2
2
  use temporal_client::{ClientOptionsBuilder, TestService, WorkflowService};
3
3
  use temporal_sdk_core::ephemeral_server::{
4
- EphemeralExe, EphemeralExeVersion, EphemeralServer, TemporaliteConfigBuilder,
5
- TestServerConfigBuilder,
4
+ EphemeralExe, EphemeralExeVersion, EphemeralServer, TemporalDevServerConfigBuilder,
5
+ TemporaliteConfigBuilder, TestServerConfigBuilder,
6
6
  };
7
7
  use temporal_sdk_core_protos::temporal::api::workflowservice::v1::DescribeNamespaceRequest;
8
8
  use temporal_sdk_core_test_utils::{default_cached_download, NAMESPACE};
9
9
  use url::Url;
10
10
 
11
+ #[tokio::test]
12
+ async fn temporal_cli_default() {
13
+ let config = TemporalDevServerConfigBuilder::default()
14
+ .exe(default_cached_download())
15
+ .build()
16
+ .unwrap();
17
+ let mut server = config.start_server().await.unwrap();
18
+ assert_ephemeral_server(&server).await;
19
+ server.shutdown().await.unwrap();
20
+ }
21
+
22
+ #[tokio::test]
23
+ async fn temporal_cli_fixed() {
24
+ let config = TemporalDevServerConfigBuilder::default()
25
+ .exe(fixed_cached_download("v0.4.0"))
26
+ .build()
27
+ .unwrap();
28
+ let mut server = config.start_server().await.unwrap();
29
+ assert_ephemeral_server(&server).await;
30
+ server.shutdown().await.unwrap();
31
+ }
32
+
11
33
  #[tokio::test]
12
34
  async fn temporalite_default() {
13
35
  let config = TemporaliteConfigBuilder::default()
@@ -22,7 +44,7 @@ async fn temporalite_default() {
22
44
  #[tokio::test]
23
45
  async fn temporalite_fixed() {
24
46
  let config = TemporaliteConfigBuilder::default()
25
- .exe(fixed_cached_download("v0.1.1"))
47
+ .exe(fixed_cached_download("v0.2.0"))
26
48
  .build()
27
49
  .unwrap();
28
50
  let mut server = config.start_server().await.unwrap();
@@ -13,10 +13,15 @@ use temporal_sdk_core_protos::{
13
13
  workflow_completion::WorkflowActivationCompletion,
14
14
  ActivityHeartbeat, ActivityTaskCompletion, AsJsonPayloadExt, IntoCompletion,
15
15
  },
16
- temporal::api::common::v1::{Payload, RetryPolicy},
16
+ temporal::api::{
17
+ common::v1::{Payload, RetryPolicy},
18
+ enums::v1::TimeoutType,
19
+ },
20
+ DEFAULT_ACTIVITY_TYPE,
17
21
  };
18
22
  use temporal_sdk_core_test_utils::{
19
- init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
23
+ drain_pollers_and_shutdown, init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter,
24
+ WorkerTestHelpers,
20
25
  };
21
26
  use tokio::time::sleep;
22
27
 
@@ -46,7 +51,7 @@ async fn activity_heartbeat() {
46
51
  assert_matches!(
47
52
  task.variant,
48
53
  Some(activity_task::Variant::Start(start_activity)) => {
49
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
54
+ assert_eq!(start_activity.activity_type, DEFAULT_ACTIVITY_TYPE.to_string())
50
55
  }
51
56
  );
52
57
  // Heartbeat timeout is set to 1 second, this loop is going to send heartbeat every 100ms.
@@ -166,7 +171,7 @@ async fn many_act_fails_with_heartbeats() {
166
171
  },]
167
172
  );
168
173
  core.complete_execution(&task.run_id).await;
169
- core.shutdown().await;
174
+ drain_pollers_and_shutdown(&core).await;
170
175
  }
171
176
 
172
177
  #[tokio::test]
@@ -196,7 +201,7 @@ async fn activity_doesnt_heartbeat_hits_timeout_then_completes() {
196
201
  ..Default::default()
197
202
  })
198
203
  .await;
199
- assert!(res.timed_out());
204
+ assert_eq!(res.timed_out(), Some(TimeoutType::Heartbeat));
200
205
  Ok(().into())
201
206
  });
202
207
 
@@ -1,18 +1,34 @@
1
- use temporal_client::WorkflowService;
2
- use temporal_sdk_core::CoreRuntime;
3
- use temporal_sdk_core_api::telemetry::MetricsExporter;
4
- use temporal_sdk_core_protos::temporal::api::workflowservice::v1::ListNamespacesRequest;
5
- use temporal_sdk_core_test_utils::{get_integ_server_options, get_integ_telem_options};
1
+ use std::{sync::Arc, time::Duration};
2
+ use temporal_client::{WorkflowClientTrait, WorkflowOptions, WorkflowService};
3
+ use temporal_sdk_core::{init_worker, CoreRuntime};
4
+ use temporal_sdk_core_api::{telemetry::MetricsExporter, worker::WorkerConfigBuilder, Worker};
5
+ use temporal_sdk_core_protos::{
6
+ coresdk::{
7
+ activity_result::ActivityExecutionResult,
8
+ workflow_commands::{ScheduleActivity, ScheduleLocalActivity},
9
+ workflow_completion::WorkflowActivationCompletion,
10
+ ActivityTaskCompletion,
11
+ },
12
+ temporal::api::{enums::v1::WorkflowIdReusePolicy, workflowservice::v1::ListNamespacesRequest},
13
+ };
14
+ use temporal_sdk_core_test_utils::{get_integ_server_options, get_integ_telem_options, NAMESPACE};
15
+ use tokio::sync::Barrier;
16
+
17
+ static ANY_PORT: &str = "127.0.0.1:0";
18
+
19
+ async fn get_text(endpoint: String) -> String {
20
+ reqwest::get(endpoint).await.unwrap().text().await.unwrap()
21
+ }
6
22
 
7
23
  #[tokio::test]
8
24
  async fn prometheus_metrics_exported() {
9
25
  let mut telemopts = get_integ_telem_options();
10
- let addr = "127.0.0.1:10919";
11
- telemopts.metrics = Some(MetricsExporter::Prometheus(addr.parse().unwrap()));
26
+ telemopts.metrics = Some(MetricsExporter::Prometheus(ANY_PORT.parse().unwrap()));
12
27
  let rt = CoreRuntime::new_assume_tokio(telemopts).unwrap();
28
+ let addr = rt.telemetry().prom_port().unwrap();
13
29
  let opts = get_integ_server_options();
14
30
  let mut raw_client = opts
15
- .connect_no_namespace(rt.metric_meter(), None)
31
+ .connect_no_namespace(rt.metric_meter().as_deref(), None)
16
32
  .await
17
33
  .unwrap();
18
34
  assert!(raw_client.get_client().capabilities().is_some());
@@ -22,16 +38,202 @@ async fn prometheus_metrics_exported() {
22
38
  .await
23
39
  .unwrap();
24
40
 
25
- let body = reqwest::get(format!("http://{}/metrics", addr))
26
- .await
27
- .unwrap()
28
- .text()
29
- .await
30
- .unwrap();
41
+ let body = get_text(format!("http://{addr}/metrics")).await;
31
42
  assert!(body.contains(
32
- "request_latency_count{operation=\"ListNamespaces\",service_name=\"temporal-core-sdk\"} 1"
43
+ "temporal_request_latency_count{operation=\"ListNamespaces\",service_name=\"temporal-core-sdk\"} 1"
33
44
  ));
34
45
  assert!(body.contains(
35
- "request_latency_count{operation=\"GetSystemInfo\",service_name=\"temporal-core-sdk\"} 1"
46
+ "temporal_request_latency_count{operation=\"GetSystemInfo\",service_name=\"temporal-core-sdk\"} 1"
36
47
  ));
37
48
  }
49
+
50
+ #[tokio::test]
51
+ async fn one_slot_worker_reports_available_slot() {
52
+ let mut telemopts = get_integ_telem_options();
53
+ let tq = "one_slot_worker_tq";
54
+ telemopts.metrics = Some(MetricsExporter::Prometheus(ANY_PORT.parse().unwrap()));
55
+ let rt = CoreRuntime::new_assume_tokio(telemopts).unwrap();
56
+ let addr = rt.telemetry().prom_port().unwrap();
57
+
58
+ let worker_cfg = WorkerConfigBuilder::default()
59
+ .namespace(NAMESPACE)
60
+ .task_queue(tq)
61
+ .worker_build_id("test_build_id")
62
+ .max_cached_workflows(1_usize)
63
+ .max_outstanding_activities(1_usize)
64
+ .max_outstanding_local_activities(1_usize)
65
+ .max_outstanding_workflow_tasks(1_usize)
66
+ .build()
67
+ .unwrap();
68
+
69
+ let client = Arc::new(
70
+ get_integ_server_options()
71
+ .connect(worker_cfg.namespace.clone(), None, None)
72
+ .await
73
+ .expect("Must connect"),
74
+ );
75
+ let worker = init_worker(&rt, worker_cfg, client.clone()).expect("Worker inits cleanly");
76
+ let wf_task_barr = Barrier::new(2);
77
+ let act_task_barr = Barrier::new(2);
78
+
79
+ let wf_polling = async {
80
+ let task = worker.poll_workflow_activation().await.unwrap();
81
+ wf_task_barr.wait().await;
82
+ wf_task_barr.wait().await;
83
+ worker
84
+ .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
85
+ task.run_id,
86
+ ScheduleActivity {
87
+ seq: 1,
88
+ activity_id: "1".to_string(),
89
+ activity_type: "test_act".to_string(),
90
+ task_queue: tq.to_string(),
91
+ start_to_close_timeout: Some(prost_dur!(from_secs(30))),
92
+ ..Default::default()
93
+ }
94
+ .into(),
95
+ ))
96
+ .await
97
+ .unwrap();
98
+ wf_task_barr.wait().await;
99
+
100
+ let task = worker.poll_workflow_activation().await.unwrap();
101
+ worker
102
+ .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
103
+ task.run_id,
104
+ ScheduleLocalActivity {
105
+ seq: 2,
106
+ activity_id: "2".to_string(),
107
+ activity_type: "test_act".to_string(),
108
+ start_to_close_timeout: Some(prost_dur!(from_secs(30))),
109
+ ..Default::default()
110
+ }
111
+ .into(),
112
+ ))
113
+ .await
114
+ .unwrap();
115
+ };
116
+
117
+ let act_polling = async {
118
+ let task = worker.poll_activity_task().await.unwrap();
119
+ act_task_barr.wait().await;
120
+ worker
121
+ .complete_activity_task(ActivityTaskCompletion {
122
+ task_token: task.task_token,
123
+ result: Some(ActivityExecutionResult::ok(vec![1].into())),
124
+ })
125
+ .await
126
+ .unwrap();
127
+ act_task_barr.wait().await;
128
+
129
+ let task = worker.poll_activity_task().await.unwrap();
130
+ act_task_barr.wait().await;
131
+ act_task_barr.wait().await;
132
+ worker
133
+ .complete_activity_task(ActivityTaskCompletion {
134
+ task_token: task.task_token,
135
+ result: Some(ActivityExecutionResult::ok(vec![1].into())),
136
+ })
137
+ .await
138
+ .unwrap();
139
+ act_task_barr.wait().await;
140
+ };
141
+
142
+ let testing = async {
143
+ // Wait just a beat for the poller to initiate
144
+ tokio::time::sleep(Duration::from_millis(50)).await;
145
+ let body = get_text(format!("http://{addr}/metrics")).await;
146
+ assert!(body.contains(&format!(
147
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
148
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
149
+ worker_type=\"WorkflowWorker\"}} 1"
150
+ )));
151
+
152
+ // Start a workflow so that a task will get delivered
153
+ client
154
+ .start_workflow(
155
+ vec![],
156
+ tq.to_owned(),
157
+ "one_slot_metric_test".to_owned(),
158
+ "whatever".to_string(),
159
+ None,
160
+ WorkflowOptions {
161
+ id_reuse_policy: WorkflowIdReusePolicy::TerminateIfRunning,
162
+ execution_timeout: Some(Duration::from_secs(5)),
163
+ ..Default::default()
164
+ },
165
+ )
166
+ .await
167
+ .unwrap();
168
+
169
+ wf_task_barr.wait().await;
170
+
171
+ // At this point the workflow task is outstanding, so there should be 0 slots, and
172
+ // the activities haven't started, so there should be 1 each.
173
+ let body = get_text(format!("http://{addr}/metrics")).await;
174
+ assert!(body.contains(&format!(
175
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
176
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
177
+ worker_type=\"WorkflowWorker\"}} 0"
178
+ )));
179
+ assert!(body.contains(&format!(
180
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
181
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
182
+ worker_type=\"ActivityWorker\"}} 1"
183
+ )));
184
+ assert!(body.contains(&format!(
185
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
186
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
187
+ worker_type=\"LocalActivityWorker\"}} 1"
188
+ )));
189
+
190
+ // Now we allow the complete to proceed. Once it goes through, there should be 1 WFT slot
191
+ // open but 0 activity slots
192
+ wf_task_barr.wait().await;
193
+ wf_task_barr.wait().await;
194
+ // Sometimes the recording takes an extra bit. 🤷
195
+ tokio::time::sleep(Duration::from_millis(100)).await;
196
+ let body = get_text(format!("http://{addr}/metrics")).await;
197
+ assert!(body.contains(&format!(
198
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
199
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
200
+ worker_type=\"WorkflowWorker\"}} 1"
201
+ )));
202
+ assert!(body.contains(&format!(
203
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
204
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
205
+ worker_type=\"ActivityWorker\"}} 0"
206
+ )));
207
+
208
+ // Now complete the activity and watch it go up
209
+ act_task_barr.wait().await;
210
+ // Wait for completion to finish
211
+ act_task_barr.wait().await;
212
+ let body = get_text(format!("http://{addr}/metrics")).await;
213
+ assert!(body.contains(&format!(
214
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
215
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
216
+ worker_type=\"ActivityWorker\"}} 1"
217
+ )));
218
+
219
+ // Proceed to local activity command
220
+ act_task_barr.wait().await;
221
+ // Ensure that, once we have the LA task, slots are 0
222
+ let body = get_text(format!("http://{addr}/metrics")).await;
223
+ assert!(body.contains(&format!(
224
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
225
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
226
+ worker_type=\"LocalActivityWorker\"}} 0"
227
+ )));
228
+ // When completion is done, we have 1 again
229
+ act_task_barr.wait().await;
230
+ act_task_barr.wait().await;
231
+ let body = get_text(format!("http://{addr}/metrics")).await;
232
+ assert!(body.contains(&format!(
233
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
234
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
235
+ worker_type=\"LocalActivityWorker\"}} 1"
236
+ )));
237
+ };
238
+ tokio::join!(wf_polling, act_polling, testing);
239
+ }
@@ -1,8 +1,5 @@
1
1
  use assert_matches::assert_matches;
2
- use futures::future::join_all;
3
2
  use std::time::Duration;
4
- use temporal_client::WorkflowOptions;
5
- use temporal_sdk::{WfContext, WorkflowResult};
6
3
  use temporal_sdk_core_protos::coresdk::{
7
4
  activity_task::activity_task as act_task,
8
5
  workflow_activation::{workflow_activation_job, FireTimer, WorkflowActivationJob},
@@ -11,7 +8,7 @@ use temporal_sdk_core_protos::coresdk::{
11
8
  IntoCompletion,
12
9
  };
13
10
  use temporal_sdk_core_test_utils::{
14
- init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
11
+ init_core_and_create_wf, schedule_activity_cmd, WorkerTestHelpers,
15
12
  };
16
13
  use tokio::time::timeout;
17
14
 
@@ -43,15 +40,10 @@ async fn out_of_order_completion_doesnt_hang() {
43
40
  )
44
41
  .await
45
42
  .unwrap();
46
- // Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
47
- // complete it in this test as activity is try-cancelled.
43
+ // Poll activity and verify that it's been scheduled, we don't expect to complete it in this
44
+ // test as activity is try-cancelled.
48
45
  let activity_task = core.poll_activity_task().await.unwrap();
49
- assert_matches!(
50
- activity_task.variant,
51
- Some(act_task::Variant::Start(start_activity)) => {
52
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
53
- }
54
- );
46
+ assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
55
47
  // Poll workflow task and verify that activity has failed.
56
48
  let task = core.poll_workflow_activation().await.unwrap();
57
49
  assert_matches!(
@@ -96,38 +88,3 @@ async fn out_of_order_completion_doesnt_hang() {
96
88
 
97
89
  jh.await.unwrap();
98
90
  }
99
-
100
- pub async fn many_parallel_timers_longhist(ctx: WfContext) -> WorkflowResult<()> {
101
- for _ in 0..20 {
102
- let mut futs = vec![];
103
- for _ in 0..1000 {
104
- futs.push(ctx.timer(Duration::from_millis(100)));
105
- }
106
- join_all(futs).await;
107
- }
108
- Ok(().into())
109
- }
110
-
111
- // Ignored for now because I can't actually get this to produce pages. Need to generate some
112
- // large payloads I think.
113
- #[tokio::test]
114
- #[ignore]
115
- async fn can_paginate_long_history() {
116
- let wf_name = "can_paginate_long_history";
117
- let mut starter = CoreWfStarter::new(wf_name);
118
- // Do not use sticky queues so we are forced to paginate once history gets long
119
- starter.max_cached_workflows(0);
120
-
121
- let mut worker = starter.worker().await;
122
- worker.register_wf(wf_name.to_owned(), many_parallel_timers_longhist);
123
- worker
124
- .submit_wf(
125
- wf_name.to_owned(),
126
- wf_name.to_owned(),
127
- vec![],
128
- WorkflowOptions::default(),
129
- )
130
- .await
131
- .unwrap();
132
- worker.run_until_done().await.unwrap();
133
- }
@@ -10,7 +10,9 @@ use temporal_sdk_core_protos::{
10
10
  },
11
11
  temporal::api::{failure::v1::Failure, query::v1::WorkflowQuery},
12
12
  };
13
- use temporal_sdk_core_test_utils::{init_core_and_create_wf, CoreWfStarter, WorkerTestHelpers};
13
+ use temporal_sdk_core_test_utils::{
14
+ drain_pollers_and_shutdown, init_core_and_create_wf, WorkerTestHelpers,
15
+ };
14
16
 
15
17
  #[tokio::test]
16
18
  async fn simple_query_legacy() {
@@ -112,7 +114,7 @@ async fn simple_query_legacy() {
112
114
  async fn query_after_execution_complete(#[case] do_evict: bool) {
113
115
  let query_resp = b"response";
114
116
  let mut starter =
115
- init_core_and_create_wf(&format!("query_after_execution_complete-{}", do_evict)).await;
117
+ init_core_and_create_wf(&format!("query_after_execution_complete-{do_evict}")).await;
116
118
  let core = &starter.get_worker().await;
117
119
  let workflow_id = &starter.get_task_queue().to_string();
118
120
 
@@ -205,132 +207,7 @@ async fn query_after_execution_complete(#[case] do_evict: bool) {
205
207
  query_futs.push(do_workflow(true).map(|_| ()).boxed());
206
208
  }
207
209
  while query_futs.next().await.is_some() {}
208
- core.shutdown().await;
209
- }
210
-
211
- #[ignore]
212
- #[tokio::test]
213
- async fn repros_query_dropped_on_floor() {
214
- // This test reliably repros the server dropping one of the two simultaneously issued queries.
215
- let q1_resp = b"query_1_resp";
216
- let q2_resp = b"query_2_resp";
217
- let mut wf_starter = CoreWfStarter::new("repros_query_dropped_on_floor");
218
- // Easiest way I discovered to reliably trigger new query path is with a WFT timeout
219
- wf_starter.wft_timeout(Duration::from_secs(1));
220
- let core = wf_starter.get_worker().await;
221
- let task_q = wf_starter.get_task_queue().to_string();
222
- wf_starter.start_wf().await;
223
- let client = wf_starter.get_client().await;
224
-
225
- let task = core.poll_workflow_activation().await.unwrap();
226
- core.complete_timer(&task.run_id, 1, Duration::from_millis(500))
227
- .await;
228
-
229
- // Poll for a task we will time out
230
- let task = core.poll_workflow_activation().await.unwrap();
231
- tokio::time::sleep(Duration::from_secs(2)).await;
232
- // Complete now-timed-out task (add a new timer)
233
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
234
- task.run_id.clone(),
235
- vec![],
236
- ))
237
- .await
238
- .unwrap();
239
-
240
- let run_id = task.run_id.to_string();
241
- let q1_fut = async {
242
- client
243
- .query_workflow_execution(
244
- task_q.clone(),
245
- run_id,
246
- WorkflowQuery {
247
- query_type: "query_1".to_string(),
248
- query_args: Some(b"hi 1".into()),
249
- header: None,
250
- },
251
- )
252
- .await
253
- .unwrap()
254
- };
255
- let run_id = task.run_id.to_string();
256
- let q2_fut = async {
257
- client
258
- .query_workflow_execution(
259
- task_q.clone(),
260
- run_id,
261
- WorkflowQuery {
262
- query_type: "query_2".to_string(),
263
- query_args: Some(b"hi 2".into()),
264
- header: None,
265
- },
266
- )
267
- .await
268
- .unwrap()
269
- };
270
- let workflow_completions_future = async {
271
- let mut seen_q1 = false;
272
- let mut seen_q2 = false;
273
- while !seen_q1 || !seen_q2 {
274
- let task = core.poll_workflow_activation().await.unwrap();
275
-
276
- if matches!(
277
- task.jobs[0],
278
- WorkflowActivationJob {
279
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
280
- }
281
- ) {
282
- let task = core.poll_workflow_activation().await.unwrap();
283
- core.complete_timer(&task.run_id, 1, Duration::from_millis(500))
284
- .await;
285
- continue;
286
- }
287
-
288
- if matches!(
289
- task.jobs[0],
290
- WorkflowActivationJob {
291
- variant: Some(workflow_activation_job::Variant::FireTimer(_)),
292
- }
293
- ) {
294
- // If we get the timer firing after replay, be done.
295
- core.complete_execution(&task.run_id).await;
296
- }
297
-
298
- // There should be a query job (really, there should be both... server only sends one?)
299
- let query = assert_matches!(
300
- task.jobs.as_slice(),
301
- [WorkflowActivationJob {
302
- variant: Some(workflow_activation_job::Variant::QueryWorkflow(q)),
303
- }] => q
304
- );
305
- let resp = if query.query_type == "query_1" {
306
- seen_q1 = true;
307
- q1_resp
308
- } else {
309
- seen_q2 = true;
310
- q2_resp
311
- };
312
- // Complete the query
313
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
314
- task.run_id,
315
- vec![QueryResult {
316
- query_id: query.query_id.clone(),
317
- variant: Some(
318
- QuerySuccess {
319
- response: Some(resp.into()),
320
- }
321
- .into(),
322
- ),
323
- }
324
- .into()],
325
- ))
326
- .await
327
- .unwrap();
328
- }
329
- };
330
- let (q1_res, q2_res, _) = tokio::join!(q1_fut, q2_fut, workflow_completions_future);
331
- // Ensure query responses are as expected
332
- assert_eq!(&q1_res.unwrap()[0].data, q1_resp);
333
- assert_eq!(&q2_res.unwrap()[0].data, q2_resp);
210
+ drain_pollers_and_shutdown(core).await;
334
211
  }
335
212
 
336
213
  #[tokio::test]