@temporalio/core-bridge 1.7.1 → 1.7.3

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 (47) hide show
  1. package/Cargo.lock +21 -0
  2. package/lib/index.d.ts +10 -10
  3. package/package.json +4 -4
  4. package/releases/aarch64-apple-darwin/index.node +0 -0
  5. package/sdk-core/.buildkite/pipeline.yml +1 -1
  6. package/sdk-core/.cargo/config.toml +2 -0
  7. package/sdk-core/CODEOWNERS +1 -1
  8. package/sdk-core/client/src/raw.rs +15 -6
  9. package/sdk-core/core/Cargo.toml +1 -0
  10. package/sdk-core/core/src/core_tests/activity_tasks.rs +13 -5
  11. package/sdk-core/core/src/core_tests/workflow_tasks.rs +45 -77
  12. package/sdk-core/core/src/internal_flags.rs +132 -46
  13. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +10 -7
  14. package/sdk-core/core/src/worker/activities.rs +152 -142
  15. package/sdk-core/core/src/worker/client.rs +12 -8
  16. package/sdk-core/core/src/worker/mod.rs +7 -5
  17. package/sdk-core/core/src/worker/workflow/history_update.rs +733 -33
  18. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -1
  19. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +4 -1
  20. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +5 -2
  21. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +1 -1
  22. package/sdk-core/core/src/worker/workflow/managed_run.rs +0 -4
  23. package/sdk-core/protos/api_upstream/.github/workflows/publish-docs.yml +23 -0
  24. package/sdk-core/protos/api_upstream/Makefile +1 -1
  25. package/sdk-core/protos/api_upstream/buf.yaml +5 -0
  26. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +17 -0
  27. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
  28. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +6 -3
  29. package/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +1 -1
  30. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +12 -22
  31. package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +2 -2
  32. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -0
  33. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +145 -48
  34. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +19 -8
  35. package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
  36. package/sdk-core/sdk/src/workflow_context.rs +9 -1
  37. package/sdk-core/test-utils/src/lib.rs +29 -7
  38. package/sdk-core/tests/integ_tests/activity_functions.rs +5 -0
  39. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +2 -4
  40. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -1
  41. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +5 -7
  42. package/sdk-core/tests/integ_tests/workflow_tests.rs +3 -7
  43. package/sdk-core/tests/main.rs +1 -0
  44. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  45. package/releases/x86_64-apple-darwin/index.node +0 -0
  46. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  47. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
package/Cargo.lock CHANGED
@@ -517,6 +517,26 @@ dependencies = [
517
517
  "cfg-if",
518
518
  ]
519
519
 
520
+ [[package]]
521
+ name = "enum-iterator"
522
+ version = "1.4.0"
523
+ source = "registry+https://github.com/rust-lang/crates.io-index"
524
+ checksum = "706d9e7cf1c7664859d79cd524e4e53ea2b67ea03c98cc2870c5e539695d597e"
525
+ dependencies = [
526
+ "enum-iterator-derive",
527
+ ]
528
+
529
+ [[package]]
530
+ name = "enum-iterator-derive"
531
+ version = "1.2.0"
532
+ source = "registry+https://github.com/rust-lang/crates.io-index"
533
+ checksum = "355f93763ef7b0ae1c43c4d8eccc9d5848d84ad1a1d8ce61c421d1ac85a19d05"
534
+ dependencies = [
535
+ "proc-macro2",
536
+ "quote",
537
+ "syn 1.0.109",
538
+ ]
539
+
520
540
  [[package]]
521
541
  name = "enum_dispatch"
522
542
  version = "0.3.11"
@@ -2272,6 +2292,7 @@ dependencies = [
2272
2292
  "dashmap",
2273
2293
  "derive_builder",
2274
2294
  "derive_more",
2295
+ "enum-iterator",
2275
2296
  "enum_dispatch",
2276
2297
  "flate2",
2277
2298
  "futures",
package/lib/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { SpanContext } from '@opentelemetry/api';
2
2
  import type { TLSConfig } from '@temporalio/common/lib/internal-non-workflow';
3
3
  export { TLSConfig };
4
- declare type Shadow<Base, New> = Base extends object ? New extends object ? {
4
+ type Shadow<Base, New> = Base extends object ? New extends object ? {
5
5
  [K in keyof Base | keyof New]: K extends keyof Base ? K extends keyof New ? Shadow<Base[K], New[K]> : Base[K] : K extends keyof New ? New[K] : never;
6
6
  } : New : New;
7
7
  export interface RetryOptions {
@@ -74,7 +74,7 @@ export interface ForwardLogger {
74
74
  *
75
75
  * @experimental
76
76
  */
77
- export declare type Logger = ConsoleLogger | ForwardLogger;
77
+ export type Logger = ConsoleLogger | ForwardLogger;
78
78
  /**
79
79
  * OpenTelemetry Collector options for exporting metrics or traces
80
80
  *
@@ -100,13 +100,13 @@ export interface OtelCollectorExporter {
100
100
  };
101
101
  }
102
102
  /** @experimental */
103
- export declare type CompiledOtelTraceExporter = Shadow<OtelCollectorExporter, {
103
+ export type CompiledOtelTraceExporter = Shadow<OtelCollectorExporter, {
104
104
  otel: {
105
105
  metricsExportInterval?: never;
106
106
  };
107
107
  }>;
108
108
  /** @experimental */
109
- export declare type CompiledOtelMetricsExporter = Shadow<OtelCollectorExporter, {
109
+ export type CompiledOtelMetricsExporter = Shadow<OtelCollectorExporter, {
110
110
  otel: {
111
111
  metricsExportInterval: number;
112
112
  };
@@ -136,7 +136,7 @@ export interface PrometheusMetricsExporter {
136
136
  *
137
137
  * @experimental
138
138
  */
139
- export declare type MetricsExporter = {
139
+ export type MetricsExporter = {
140
140
  temporality?: 'cumulative' | 'delta';
141
141
  } & (PrometheusMetricsExporter | OtelCollectorExporter);
142
142
  /**
@@ -144,7 +144,7 @@ export declare type MetricsExporter = {
144
144
  *
145
145
  * @experimental
146
146
  */
147
- export declare type TraceExporter = OtelCollectorExporter;
147
+ export type TraceExporter = OtelCollectorExporter;
148
148
  /** @experimental */
149
149
  export interface TelemetryOptions {
150
150
  /**
@@ -216,7 +216,7 @@ export interface TelemetryOptions {
216
216
  metrics?: MetricsExporter;
217
217
  }
218
218
  /** @experimental */
219
- export declare type CompiledTelemetryOptions = {
219
+ export type CompiledTelemetryOptions = {
220
220
  noTemporalPrefixForMetrics?: boolean;
221
221
  logging: {
222
222
  filter: string;
@@ -290,7 +290,7 @@ export interface WorkerOptions {
290
290
  maxActivitiesPerSecond?: number;
291
291
  }
292
292
  /** Log level - must match rust log level names */
293
- export declare type LogLevel = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';
293
+ export type LogLevel = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';
294
294
  export interface LogEntry {
295
295
  /** Log message */
296
296
  message: string;
@@ -306,7 +306,7 @@ export interface LogEntry {
306
306
  /**
307
307
  * Which version of the executable to run.
308
308
  */
309
- export declare type EphemeralServerExecutable = {
309
+ export type EphemeralServerExecutable = {
310
310
  type: 'cached-download';
311
311
  /**
312
312
  * Download destination directory or the system's temp directory if none set.
@@ -390,7 +390,7 @@ export interface DevServerConfig {
390
390
  *
391
391
  * Both the time-skipping test server and Temporal CLI dev server are supported.
392
392
  */
393
- export declare type EphemeralServerConfig = TimeSkippingServerConfig | DevServerConfig;
393
+ export type EphemeralServerConfig = TimeSkippingServerConfig | DevServerConfig;
394
394
  export interface Worker {
395
395
  type: 'Worker';
396
396
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temporalio/core-bridge",
3
- "version": "1.7.1",
3
+ "version": "1.7.3",
4
4
  "description": "Temporal.io SDK Core<>Node bridge",
5
5
  "main": "index.js",
6
6
  "types": "lib/index.d.ts",
@@ -22,8 +22,8 @@
22
22
  "author": "Temporal Technologies Inc. <sdk@temporal.io>",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "@opentelemetry/api": "^1.3.0",
26
- "@temporalio/common": "1.7.1",
25
+ "@opentelemetry/api": "^1.4.1",
26
+ "@temporalio/common": "1.7.3",
27
27
  "arg": "^5.0.2",
28
28
  "cargo-cp-artifact": "^0.1.6",
29
29
  "which": "^2.0.2"
@@ -53,5 +53,5 @@
53
53
  "publishConfig": {
54
54
  "access": "public"
55
55
  },
56
- "gitHead": "368aa83c631555fc31cff25f4af8817d069878d8"
56
+ "gitHead": "c78237bad40342b97a0aaec97ef01763b39a04f8"
57
57
  }
@@ -17,7 +17,7 @@ steps:
17
17
  agents:
18
18
  queue: "default"
19
19
  docker: "*"
20
- command: "cargo lint"
20
+ command: "cargo lint && cargo test-lint"
21
21
  timeout_in_minutes: 15
22
22
  plugins:
23
23
  - docker-compose#v3.0.0:
@@ -4,3 +4,5 @@ wf-input-replay = ["run", "--package", "temporal-sdk-core", "--features", "save_
4
4
  "--example", "wf_input_replay", "--"]
5
5
  lint = ["clippy", "--workspace", "--examples", "--all-features",
6
6
  "--test", "integ_tests", "--test", "heavy_tests", "--", "--D", "warnings"]
7
+ test-lint = ["clippy", "--all", "--all-features", "--examples", "--workspace",
8
+ "--tests", "--", "--D", "warnings"]
@@ -1,3 +1,3 @@
1
1
  # Primary owners
2
2
 
3
- * @Sushisource @bergundy @cretz @Spikhalskiy
3
+ * @temporalio/sdk
@@ -740,9 +740,9 @@ proxier! {
740
740
  }
741
741
  );
742
742
  (
743
- update_worker_build_id_ordering,
744
- UpdateWorkerBuildIdOrderingRequest,
745
- UpdateWorkerBuildIdOrderingResponse,
743
+ update_worker_build_id_compatibility,
744
+ UpdateWorkerBuildIdCompatibilityRequest,
745
+ UpdateWorkerBuildIdCompatibilityResponse,
746
746
  |r| {
747
747
  let mut labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
748
748
  labels.task_q_str(r.get_ref().task_queue.clone());
@@ -750,9 +750,9 @@ proxier! {
750
750
  }
751
751
  );
752
752
  (
753
- get_worker_build_id_ordering,
754
- GetWorkerBuildIdOrderingRequest,
755
- GetWorkerBuildIdOrderingResponse,
753
+ get_worker_build_id_compatibility,
754
+ GetWorkerBuildIdCompatibilityRequest,
755
+ GetWorkerBuildIdCompatibilityResponse,
756
756
  |r| {
757
757
  let mut labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
758
758
  labels.task_q_str(r.get_ref().task_queue.clone());
@@ -768,6 +768,15 @@ proxier! {
768
768
  r.extensions_mut().insert(labels);
769
769
  }
770
770
  );
771
+ (
772
+ poll_workflow_execution_update,
773
+ PollWorkflowExecutionUpdateRequest,
774
+ PollWorkflowExecutionUpdateResponse,
775
+ |r| {
776
+ let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
777
+ r.extensions_mut().insert(labels);
778
+ }
779
+ );
771
780
  (
772
781
  start_batch_operation,
773
782
  StartBatchOperationRequest,
@@ -28,6 +28,7 @@ dashmap = "5.0"
28
28
  derive_builder = "0.12"
29
29
  derive_more = "0.99"
30
30
  enum_dispatch = "0.3"
31
+ enum-iterator = "1.4"
31
32
  flate2 = "1.0"
32
33
  futures = "0.3"
33
34
  futures-util = "0.3"
@@ -58,7 +58,7 @@ use temporal_sdk_core_protos::{
58
58
  TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE,
59
59
  };
60
60
  use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd, TestWorker};
61
- use tokio::{sync::Barrier, time::sleep};
61
+ use tokio::{join, sync::Barrier, time::sleep};
62
62
  use tokio_util::sync::CancellationToken;
63
63
 
64
64
  fn three_tasks() -> VecDeque<PollActivityTaskQueueResponse> {
@@ -288,7 +288,7 @@ async fn activity_cancel_interrupts_poll() {
288
288
  // Perform first poll to get the activity registered
289
289
  let act = core.poll_activity_task().await.unwrap();
290
290
  // Poll should block until heartbeat is sent, issuing the cancel, and interrupting the poll
291
- tokio::join! {
291
+ join! {
292
292
  async {
293
293
  core.record_activity_heartbeat(ActivityHeartbeat {
294
294
  task_token: act.task_token,
@@ -984,7 +984,7 @@ async fn activity_tasks_from_completion_reserve_slots() {
984
984
  // This wf poll should *not* set the flag that it wants tasks back since both slots are
985
985
  // occupied
986
986
  let run_fut = async { worker.run_until_done().await.unwrap() };
987
- tokio::join!(run_fut, act_completer);
987
+ join!(run_fut, act_completer);
988
988
  }
989
989
 
990
990
  #[tokio::test]
@@ -1052,9 +1052,11 @@ async fn cant_complete_activity_with_unset_result_payload() {
1052
1052
  )
1053
1053
  }
1054
1054
 
1055
+ #[rstest::rstest]
1055
1056
  #[tokio::test]
1056
- async fn graceful_shutdown() {
1057
+ async fn graceful_shutdown(#[values(true, false)] at_max_outstanding: bool) {
1057
1058
  let _task_q = "q";
1059
+ let grace_period = Duration::from_millis(200);
1058
1060
  let mut tasks = three_tasks();
1059
1061
  let mut mock_client = mock_workflow_client();
1060
1062
  mock_client
@@ -1067,15 +1069,21 @@ async fn graceful_shutdown() {
1067
1069
  .times(3)
1068
1070
  .returning(|_, _| Ok(Default::default()));
1069
1071
 
1072
+ let max_outstanding = if at_max_outstanding { 3_usize } else { 100 };
1070
1073
  let worker = Worker::new_test(
1071
1074
  test_worker_cfg()
1072
- .graceful_shutdown_period(Duration::from_millis(500))
1075
+ .graceful_shutdown_period(grace_period)
1076
+ .max_outstanding_activities(max_outstanding)
1073
1077
  .build()
1074
1078
  .unwrap(),
1075
1079
  mock_client,
1076
1080
  );
1077
1081
 
1078
1082
  let _1 = worker.poll_activity_task().await.unwrap();
1083
+
1084
+ // Wait at least the grace period after one poll - ensuring it doesn't trigger prematurely
1085
+ tokio::time::sleep(grace_period.mul_f32(1.1)).await;
1086
+
1079
1087
  let _2 = worker.poll_activity_task().await.unwrap();
1080
1088
  let _3 = worker.poll_activity_task().await.unwrap();
1081
1089
 
@@ -1,5 +1,7 @@
1
1
  use crate::{
2
- advance_fut, job_assert,
2
+ advance_fut,
3
+ internal_flags::CoreInternalFlags,
4
+ job_assert,
3
5
  replay::TestHistoryBuilder,
4
6
  test_help::{
5
7
  build_fake_worker, build_mock_pollers, build_multihist_mock_sg, canned_histories,
@@ -14,9 +16,9 @@ use crate::{
14
16
  use futures::{stream, FutureExt};
15
17
  use rstest::{fixture, rstest};
16
18
  use std::{
17
- collections::{HashMap, VecDeque},
19
+ collections::{HashMap, HashSet, VecDeque},
18
20
  sync::{
19
- atomic::{AtomicBool, AtomicU64, Ordering},
21
+ atomic::{AtomicU64, Ordering},
20
22
  Arc,
21
23
  },
22
24
  time::Duration,
@@ -54,9 +56,7 @@ use temporal_sdk_core_protos::{
54
56
  },
55
57
  DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE,
56
58
  };
57
- use temporal_sdk_core_test_utils::{
58
- fanout_tasks, schedule_activity_cmd, start_timer_cmd, WorkerTestHelpers,
59
- };
59
+ use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd, WorkerTestHelpers};
60
60
  use tokio::{
61
61
  join,
62
62
  sync::{Barrier, Semaphore},
@@ -896,10 +896,7 @@ async fn workflow_failures_only_reported_once() {
896
896
  #[tokio::test]
897
897
  async fn max_wft_respected() {
898
898
  let total_wfs = 100;
899
- let wf_ids: Vec<_> = (0..total_wfs)
900
- .into_iter()
901
- .map(|i| format!("fake-wf-{i}"))
902
- .collect();
899
+ let wf_ids: Vec<_> = (0..total_wfs).map(|i| format!("fake-wf-{i}")).collect();
903
900
  let hists = wf_ids.iter().map(|wf_id| {
904
901
  let hist = canned_histories::single_timer("1");
905
902
  FakeWfResponses {
@@ -1027,7 +1024,7 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
1027
1024
  #[tokio::test]
1028
1025
  async fn lots_of_workflows() {
1029
1026
  let total_wfs = 500;
1030
- let hists = (0..total_wfs).into_iter().map(|i| {
1027
+ let hists = (0..total_wfs).map(|i| {
1031
1028
  let wf_id = format!("fake-wf-{i}");
1032
1029
  let hist = canned_histories::single_timer("1");
1033
1030
  FakeWfResponses {
@@ -1705,9 +1702,7 @@ async fn pagination_works_with_tasks_from_completion() {
1705
1702
  t.add_by_type(EventType::WorkflowExecutionStarted);
1706
1703
  t.add_full_wf_task();
1707
1704
  t.add_we_signaled("sig", vec![]);
1708
- t.add_full_wf_task();
1709
- t.add_workflow_execution_completed();
1710
- let get_exec_resp: GetWorkflowExecutionHistoryResponse = t.get_history_info(2).unwrap().into();
1705
+ t.add_workflow_task_scheduled_and_started();
1711
1706
 
1712
1707
  let mut mock = mock_workflow_client();
1713
1708
  let mut needs_pag_resp = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2)).resp;
@@ -1722,9 +1717,13 @@ async fn pagination_works_with_tasks_from_completion() {
1722
1717
  mock.expect_complete_workflow_task()
1723
1718
  .times(1)
1724
1719
  .returning(|_| Ok(Default::default()));
1720
+
1721
+ let get_exec_resp: GetWorkflowExecutionHistoryResponse =
1722
+ t.get_full_history_info().unwrap().into();
1725
1723
  mock.expect_get_workflow_execution_history()
1726
1724
  .returning(move |_, _, _| Ok(get_exec_resp.clone()))
1727
1725
  .times(1);
1726
+
1728
1727
  let mut mock = single_hist_mock_sg(wfid, t, [1], mock, true);
1729
1728
  mock.worker_cfg(|wc| wc.max_cached_workflows = 2);
1730
1729
  let core = mock_worker(mock);
@@ -2162,10 +2161,6 @@ async fn fetching_to_continue_replay_works() {
2162
2161
  t.add_full_wf_task(); // end 14
2163
2162
  let mut fetch_resp: GetWorkflowExecutionHistoryResponse =
2164
2163
  t.get_full_history_info().unwrap().into();
2165
- // Should only contain events after 7
2166
- if let Some(ref mut h) = fetch_resp.history {
2167
- h.events.retain(|e| e.event_id >= 8);
2168
- }
2169
2164
  // And indicate that even *more* needs to be fetched after this, so we see a request for the
2170
2165
  // next page happen.
2171
2166
  fetch_resp.next_page_token = vec![2];
@@ -2173,12 +2168,8 @@ async fn fetching_to_continue_replay_works() {
2173
2168
  let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
2174
2169
  t.add_timer_fired(timer_started_event_id, "1".to_string());
2175
2170
  t.add_full_wf_task();
2176
- let mut final_fetch_resp: GetWorkflowExecutionHistoryResponse =
2171
+ let final_fetch_resp: GetWorkflowExecutionHistoryResponse =
2177
2172
  t.get_full_history_info().unwrap().into();
2178
- // Should have only the final event
2179
- if let Some(ref mut h) = final_fetch_resp.history {
2180
- h.events.retain(|e| e.event_id >= 15);
2181
- }
2182
2173
 
2183
2174
  let tasks = vec![
2184
2175
  ResponseType::ToTaskNum(1),
@@ -2273,15 +2264,25 @@ async fn ensure_fetching_fail_during_complete_sends_task_failure() {
2273
2264
  t.add_full_wf_task(); // started 3
2274
2265
  t.add_we_signaled("sig1", vec![]);
2275
2266
  t.add_full_wf_task(); // started 7
2276
- t.add_we_signaled("sig2", vec![]);
2267
+
2268
+ // Need a command event after here so the paginator will know it has two complete WFTs and
2269
+ // processing can begin before needing to fetch again
2270
+ t.add_by_type(EventType::TimerStarted);
2277
2271
  t.add_full_wf_task(); // started 11
2278
2272
  t.add_workflow_execution_completed();
2279
2273
 
2280
- let mut first_poll = hist_to_poll_resp(&t, wfid, ResponseType::ToTaskNum(1)).resp;
2281
- first_poll.next_page_token = vec![1];
2282
- first_poll.previous_started_event_id = 3;
2274
+ let mut first_poll = hist_to_poll_resp(&t, wfid, ResponseType::OneTask(4)).resp;
2275
+ // History is partial so fetch will happen. We have to lie here and make up a previous started
2276
+ // which really makes no sense, otherwise the paginator eagerly fetches and will fail before we
2277
+ // ever start anything -- which is good -- but this test wants to make sure a fetching failure
2278
+ // during a completion is handled correctly. That may no longer actually be a thing that can
2279
+ // happen.
2280
+ first_poll.previous_started_event_id = 0;
2281
+ first_poll.started_event_id = 11;
2283
2282
 
2284
- let mut next_page: GetWorkflowExecutionHistoryResponse = t.get_history_info(2).unwrap().into();
2283
+ let mut next_page: GetWorkflowExecutionHistoryResponse =
2284
+ t.get_full_history_info().unwrap().into();
2285
+ next_page.history.as_mut().unwrap().events.truncate(9);
2285
2286
  next_page.next_page_token = vec![2];
2286
2287
 
2287
2288
  let mut mock = mock_workflow_client();
@@ -2291,13 +2292,10 @@ async fn ensure_fetching_fail_during_complete_sends_task_failure() {
2291
2292
  Ok(next_page.clone())
2292
2293
  })
2293
2294
  .times(1);
2294
- let mut really_empty_fetch_resp: GetWorkflowExecutionHistoryResponse =
2295
- t.get_history_info(1).unwrap().into();
2296
- really_empty_fetch_resp.history = Some(Default::default());
2297
2295
  mock.expect_get_workflow_execution_history()
2298
2296
  .returning(move |_, _, _| {
2299
2297
  error!("Called fetch second time!");
2300
- Ok(really_empty_fetch_resp.clone())
2298
+ Err(tonic::Status::not_found("Ahh broken"))
2301
2299
  })
2302
2300
  .times(1);
2303
2301
  mock.expect_fail_workflow_task()
@@ -2314,24 +2312,13 @@ async fn ensure_fetching_fail_during_complete_sends_task_failure() {
2314
2312
  .await
2315
2313
  .unwrap();
2316
2314
 
2317
- let wf_task = core.poll_workflow_activation().await.unwrap();
2318
- assert_matches!(
2319
- wf_task.jobs.as_slice(),
2320
- [WorkflowActivationJob {
2321
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
2322
- },]
2323
- );
2324
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
2325
- .await
2326
- .unwrap();
2327
-
2328
2315
  // Expect to see eviction b/c of history fetching error here.
2329
2316
  let wf_task = core.poll_workflow_activation().await.unwrap();
2330
2317
  assert_matches!(
2331
2318
  wf_task.jobs.as_slice(),
2332
2319
  [WorkflowActivationJob {
2333
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
2334
- },]
2320
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(c)),
2321
+ }] if c.message.contains("Fetching history")
2335
2322
  );
2336
2323
 
2337
2324
  core.shutdown().await;
@@ -2380,54 +2367,35 @@ async fn lang_internal_flags() {
2380
2367
  core.shutdown().await;
2381
2368
  }
2382
2369
 
2383
- // Verify we send flags to server when they're used
2370
+ // Verify we send all core internal flags on the first non-replay WFT
2384
2371
  #[tokio::test]
2385
2372
  async fn core_internal_flags() {
2386
2373
  let mut t = TestHistoryBuilder::default();
2387
2374
  t.add_by_type(EventType::WorkflowExecutionStarted);
2388
- t.add_full_wf_task();
2389
- let act_scheduled_event_id = t.add_activity_task_scheduled("act-id");
2390
- let act_started_event_id = t.add_activity_task_started(act_scheduled_event_id);
2391
- t.add_activity_task_completed(
2392
- act_scheduled_event_id,
2393
- act_started_event_id,
2394
- Default::default(),
2395
- );
2396
- t.add_full_wf_task();
2397
- t.add_workflow_execution_completed();
2375
+ t.add_workflow_task_scheduled_and_started();
2398
2376
 
2399
2377
  let mut mh = MockPollCfg::from_resp_batches(
2400
2378
  "fake_wf_id",
2401
2379
  t,
2402
- [ResponseType::ToTaskNum(1), ResponseType::ToTaskNum(2)],
2380
+ [ResponseType::ToTaskNum(1)],
2403
2381
  mock_workflow_client(),
2404
2382
  );
2405
- let first_poll = AtomicBool::new(true);
2406
2383
  mh.completion_asserts = Some(Box::new(move |c| {
2407
- if !first_poll.load(Ordering::Acquire) {
2408
- assert_matches!(c.sdk_metadata.core_used_flags.as_slice(), &[1]);
2409
- }
2410
- first_poll.store(false, Ordering::Release);
2384
+ assert_eq!(
2385
+ c.sdk_metadata
2386
+ .core_used_flags
2387
+ .iter()
2388
+ .copied()
2389
+ .collect::<HashSet<_>>(),
2390
+ CoreInternalFlags::all_except_too_high()
2391
+ .map(|f| f as u32)
2392
+ .collect()
2393
+ );
2411
2394
  }));
2412
2395
  let mut mock = build_mock_pollers(mh);
2413
2396
  mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
2414
2397
  let core = mock_worker(mock);
2415
2398
 
2416
- let act = core.poll_workflow_activation().await.unwrap();
2417
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
2418
- act.run_id,
2419
- schedule_activity_cmd(
2420
- 1,
2421
- "whatever",
2422
- "act-id",
2423
- ActivityCancellationType::TryCancel,
2424
- Duration::from_secs(60),
2425
- Duration::from_secs(60),
2426
- ),
2427
- ))
2428
- .await
2429
- .unwrap();
2430
-
2431
2399
  let act = core.poll_workflow_activation().await.unwrap();
2432
2400
  core.complete_execution(&act.run_id).await;
2433
2401
  core.shutdown().await;