temporalio 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (232) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +175 -4
  3. data/bridge/Cargo.lock +44 -21
  4. data/bridge/Cargo.toml +1 -0
  5. data/bridge/sdk-core/Cargo.toml +1 -1
  6. data/bridge/sdk-core/README.md +1 -4
  7. data/bridge/sdk-core/client/Cargo.toml +1 -1
  8. data/bridge/sdk-core/client/src/lib.rs +12 -20
  9. data/bridge/sdk-core/client/src/raw.rs +9 -8
  10. data/bridge/sdk-core/client/src/retry.rs +100 -23
  11. data/bridge/sdk-core/core/Cargo.toml +7 -7
  12. data/bridge/sdk-core/core/benches/workflow_replay.rs +13 -10
  13. data/bridge/sdk-core/core/src/abstractions.rs +22 -22
  14. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +146 -43
  15. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +419 -9
  16. data/bridge/sdk-core/core/src/core_tests/queries.rs +247 -89
  17. data/bridge/sdk-core/core/src/core_tests/workers.rs +2 -2
  18. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  19. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +47 -27
  20. data/bridge/sdk-core/core/src/lib.rs +139 -32
  21. data/bridge/sdk-core/core/src/protosext/mod.rs +1 -1
  22. data/bridge/sdk-core/core/src/replay/mod.rs +185 -41
  23. data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
  24. data/bridge/sdk-core/core/src/telemetry/metrics.rs +184 -139
  25. data/bridge/sdk-core/core/src/telemetry/mod.rs +310 -315
  26. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
  27. data/bridge/sdk-core/core/src/test_help/mod.rs +23 -9
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +12 -6
  29. data/bridge/sdk-core/core/src/worker/activities.rs +40 -23
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +1 -1
  31. data/bridge/sdk-core/core/src/worker/client.rs +30 -4
  32. data/bridge/sdk-core/core/src/worker/mod.rs +23 -19
  33. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
  34. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
  35. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +24 -22
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +1 -1
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +233 -217
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
  53. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
  55. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +86 -29
  56. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
  57. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
  58. data/bridge/sdk-core/core-api/Cargo.toml +4 -3
  59. data/bridge/sdk-core/core-api/src/lib.rs +1 -43
  60. data/bridge/sdk-core/core-api/src/telemetry.rs +147 -0
  61. data/bridge/sdk-core/core-api/src/worker.rs +13 -0
  62. data/bridge/sdk-core/etc/deps.svg +115 -140
  63. data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
  64. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  65. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  66. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  67. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -3
  68. data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
  69. data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
  70. data/bridge/sdk-core/protos/api_upstream/{temporal/api/update/v1/message.proto → build/tools.go} +6 -23
  71. data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -9
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +20 -19
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +4 -4
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +5 -3
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +23 -2
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/{cluster.proto → interaction_type.proto} +10 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  85. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  86. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
  87. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  88. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  89. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  90. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  91. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +26 -19
  92. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
  93. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
  94. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +21 -61
  95. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -21
  96. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  97. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  98. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +110 -31
  99. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +4 -4
  100. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  101. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +3 -2
  102. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -16
  103. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +17 -3
  104. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  105. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
  106. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  107. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  108. data/bridge/sdk-core/sdk/Cargo.toml +2 -2
  109. data/bridge/sdk-core/sdk/src/interceptors.rs +36 -3
  110. data/bridge/sdk-core/sdk/src/lib.rs +7 -5
  111. data/bridge/sdk-core/sdk/src/workflow_context.rs +13 -2
  112. data/bridge/sdk-core/sdk/src/workflow_future.rs +3 -7
  113. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +1 -1
  114. data/bridge/sdk-core/sdk-core-protos/build.rs +0 -1
  115. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +65 -18
  116. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
  117. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +104 -44
  118. data/bridge/sdk-core/test-utils/Cargo.toml +2 -1
  119. data/bridge/sdk-core/test-utils/src/lib.rs +81 -29
  120. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
  121. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
  122. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +167 -13
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
  127. data/bridge/sdk-core/tests/main.rs +6 -4
  128. data/bridge/src/connection.rs +81 -62
  129. data/bridge/src/lib.rs +92 -33
  130. data/bridge/src/runtime.rs +9 -2
  131. data/bridge/src/worker.rs +53 -2
  132. data/lib/bridge.so +0 -0
  133. data/lib/gen/temporal/api/batch/v1/message_pb.rb +8 -6
  134. data/lib/gen/temporal/api/command/v1/message_pb.rb +17 -9
  135. data/lib/gen/temporal/api/common/v1/message_pb.rb +1 -1
  136. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +2 -1
  137. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +3 -1
  138. data/lib/gen/temporal/api/enums/v1/common_pb.rb +2 -1
  139. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -2
  140. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +7 -1
  141. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +25 -0
  142. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +1 -1
  143. data/lib/gen/temporal/api/enums/v1/query_pb.rb +1 -1
  144. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +1 -1
  145. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +1 -1
  146. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +1 -1
  147. data/lib/gen/temporal/api/enums/v1/update_pb.rb +1 -6
  148. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +1 -1
  149. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +1 -1
  150. data/lib/gen/temporal/api/failure/v1/message_pb.rb +1 -1
  151. data/lib/gen/temporal/api/filter/v1/message_pb.rb +1 -1
  152. data/lib/gen/temporal/api/history/v1/message_pb.rb +19 -18
  153. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +49 -0
  154. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -1
  155. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +11 -51
  156. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +1 -1
  157. data/lib/gen/temporal/api/query/v1/message_pb.rb +1 -1
  158. data/lib/gen/temporal/api/replication/v1/message_pb.rb +1 -1
  159. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +22 -1
  160. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +2 -2
  161. data/lib/gen/temporal/api/version/v1/message_pb.rb +1 -1
  162. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +2 -1
  163. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +27 -10
  164. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +1 -1
  165. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +1 -0
  166. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +5 -1
  167. data/lib/temporalio/activity/context.rb +97 -0
  168. data/lib/temporalio/activity/info.rb +67 -0
  169. data/lib/temporalio/activity.rb +85 -0
  170. data/lib/temporalio/bridge/error.rb +8 -0
  171. data/lib/temporalio/bridge.rb +14 -0
  172. data/lib/{temporal → temporalio}/client/implementation.rb +49 -48
  173. data/lib/{temporal → temporalio}/client/workflow_handle.rb +35 -35
  174. data/lib/{temporal → temporalio}/client.rb +19 -32
  175. data/lib/{temporal → temporalio}/connection.rb +238 -223
  176. data/lib/{temporal → temporalio}/data_converter.rb +76 -35
  177. data/lib/{temporal → temporalio}/error/failure.rb +6 -6
  178. data/lib/{temporal → temporalio}/error/workflow_failure.rb +4 -2
  179. data/lib/{temporal → temporalio}/errors.rb +19 -1
  180. data/lib/{temporal → temporalio}/failure_converter/base.rb +5 -5
  181. data/lib/{temporal → temporalio}/failure_converter/basic.rb +58 -52
  182. data/lib/temporalio/failure_converter.rb +7 -0
  183. data/lib/{temporal → temporalio}/interceptor/chain.rb +2 -1
  184. data/lib/{temporal → temporalio}/interceptor/client.rb +22 -1
  185. data/lib/{temporal → temporalio}/payload_codec/base.rb +5 -5
  186. data/lib/{temporal → temporalio}/payload_converter/base.rb +3 -3
  187. data/lib/{temporal → temporalio}/payload_converter/bytes.rb +4 -3
  188. data/lib/{temporal → temporalio}/payload_converter/composite.rb +7 -5
  189. data/lib/{temporal → temporalio}/payload_converter/encoding_base.rb +4 -4
  190. data/lib/{temporal → temporalio}/payload_converter/json.rb +4 -3
  191. data/lib/{temporal → temporalio}/payload_converter/nil.rb +4 -3
  192. data/lib/temporalio/payload_converter.rb +14 -0
  193. data/lib/{temporal → temporalio}/retry_policy.rb +4 -4
  194. data/lib/{temporal → temporalio}/retry_state.rb +1 -1
  195. data/lib/temporalio/runtime.rb +25 -0
  196. data/lib/{temporal → temporalio}/timeout_type.rb +2 -2
  197. data/lib/temporalio/version.rb +3 -0
  198. data/lib/temporalio/worker/activity_runner.rb +92 -0
  199. data/lib/temporalio/worker/activity_worker.rb +138 -0
  200. data/lib/temporalio/worker/reactor.rb +46 -0
  201. data/lib/temporalio/worker/runner.rb +63 -0
  202. data/lib/temporalio/worker/sync_worker.rb +88 -0
  203. data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
  204. data/lib/temporalio/worker.rb +198 -0
  205. data/lib/{temporal → temporalio}/workflow/execution_info.rb +4 -4
  206. data/lib/{temporal → temporalio}/workflow/execution_status.rb +1 -1
  207. data/lib/{temporal → temporalio}/workflow/id_reuse_policy.rb +6 -6
  208. data/lib/{temporal → temporalio}/workflow/query_reject_condition.rb +5 -5
  209. data/lib/temporalio.rb +12 -3
  210. data/temporalio.gemspec +7 -3
  211. metadata +79 -56
  212. data/bridge/sdk-core/bridge-ffi/Cargo.toml +0 -24
  213. data/bridge/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  214. data/bridge/sdk-core/bridge-ffi/build.rs +0 -25
  215. data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -249
  216. data/bridge/sdk-core/bridge-ffi/src/lib.rs +0 -825
  217. data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +0 -211
  218. data/bridge/sdk-core/core/src/log_export.rs +0 -62
  219. data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
  220. data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
  221. data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
  222. data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  223. data/bridge/sdk-core/sdk/src/conversions.rs +0 -8
  224. data/lib/gen/temporal/api/cluster/v1/message_pb.rb +0 -67
  225. data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +0 -26
  226. data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -26
  227. data/lib/temporal/bridge.rb +0 -14
  228. data/lib/temporal/failure_converter.rb +0 -8
  229. data/lib/temporal/payload_converter.rb +0 -14
  230. data/lib/temporal/runtime.rb +0 -22
  231. data/lib/temporal/version.rb +0 -3
  232. data/lib/temporal.rb +0 -8
@@ -1,7 +1,7 @@
1
1
  use crate::{
2
2
  test_help::{
3
3
  build_mock_pollers, canned_histories, hist_to_poll_resp, mock_worker, single_hist_mock_sg,
4
- MockPollCfg, ResponseType, TEST_Q,
4
+ MockPollCfg, ResponseType,
5
5
  },
6
6
  worker::{client::mocks::mock_workflow_client, LEGACY_QUERY_ID},
7
7
  };
@@ -16,22 +16,24 @@ use temporal_sdk_core_protos::{
16
16
  remove_from_cache::EvictionReason, workflow_activation_job, WorkflowActivationJob,
17
17
  },
18
18
  workflow_commands::{
19
- ActivityCancellationType, CompleteWorkflowExecution, ContinueAsNewWorkflowExecution,
20
- QueryResult, QuerySuccess, RequestCancelActivity,
19
+ query_result, ActivityCancellationType, CompleteWorkflowExecution,
20
+ ContinueAsNewWorkflowExecution, QueryResult, QuerySuccess, RequestCancelActivity,
21
21
  },
22
22
  workflow_completion::WorkflowActivationCompletion,
23
23
  },
24
24
  temporal::api::{
25
25
  common::v1::Payload,
26
+ enums::v1::EventType,
26
27
  failure::v1::Failure,
27
- history::v1::History,
28
+ history::v1::{history_event, ActivityTaskCancelRequestedEventAttributes, History},
28
29
  query::v1::WorkflowQuery,
29
30
  workflowservice::v1::{
30
31
  GetWorkflowExecutionHistoryResponse, RespondWorkflowTaskCompletedResponse,
31
32
  },
32
33
  },
34
+ TestHistoryBuilder,
33
35
  };
34
- use temporal_sdk_core_test_utils::{schedule_activity_cmd, start_timer_cmd};
36
+ use temporal_sdk_core_test_utils::{schedule_activity_cmd, start_timer_cmd, WorkerTestHelpers};
35
37
 
36
38
  #[rstest::rstest]
37
39
  #[case::with_history(true)]
@@ -44,9 +46,9 @@ async fn legacy_query(#[case] include_history: bool) {
44
46
  let mut header = HashMap::new();
45
47
  header.insert("head".to_string(), Payload::from(b"er"));
46
48
  let tasks = [
47
- hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
49
+ hist_to_poll_resp(&t, wfid.to_owned(), 1.into()),
48
50
  {
49
- let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string());
51
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
50
52
  pr.query = Some(WorkflowQuery {
51
53
  query_type: "query-type".to_string(),
52
54
  query_args: Some(b"hi".into()),
@@ -57,7 +59,7 @@ async fn legacy_query(#[case] include_history: bool) {
57
59
  }
58
60
  pr
59
61
  },
60
- hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()),
62
+ hist_to_poll_resp(&t, wfid.to_owned(), 2.into()),
61
63
  ];
62
64
  let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
63
65
  mock.num_expected_legacy_query_resps = 1;
@@ -155,29 +157,21 @@ async fn new_queries(#[case] num_queries: usize) {
155
157
  let t = canned_histories::single_timer("1");
156
158
  let mut header = HashMap::new();
157
159
  header.insert("head".to_string(), Payload::from(b"er"));
158
- let tasks = VecDeque::from(vec![
159
- hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
160
- {
161
- let mut pr = hist_to_poll_resp(
162
- &t,
163
- wfid.to_owned(),
164
- ResponseType::OneTask(2),
165
- TEST_Q.to_string(),
160
+ let tasks = VecDeque::from(vec![hist_to_poll_resp(&t, wfid.to_owned(), 1.into()), {
161
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2));
162
+ pr.queries = HashMap::new();
163
+ for i in 1..=num_queries {
164
+ pr.queries.insert(
165
+ format!("q{}", i),
166
+ WorkflowQuery {
167
+ query_type: "query-type".to_string(),
168
+ query_args: Some(b"hi".into()),
169
+ header: Some(header.clone().into()),
170
+ },
166
171
  );
167
- pr.queries = HashMap::new();
168
- for i in 1..=num_queries {
169
- pr.queries.insert(
170
- format!("q{}", i),
171
- WorkflowQuery {
172
- query_type: "query-type".to_string(),
173
- query_args: Some(b"hi".into()),
174
- header: Some(header.clone().into()),
175
- },
176
- );
177
- }
178
- pr
179
- },
180
- ]);
172
+ }
173
+ pr
174
+ }]);
181
175
  let mut mock_client = mock_workflow_client();
182
176
  mock_client.expect_respond_legacy_query().times(0);
183
177
  let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
@@ -237,19 +231,16 @@ async fn new_queries(#[case] num_queries: usize) {
237
231
  async fn legacy_query_failure_on_wft_failure() {
238
232
  let wfid = "fake_wf_id";
239
233
  let t = canned_histories::single_timer("1");
240
- let tasks = VecDeque::from(vec![
241
- hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
242
- {
243
- let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string());
244
- pr.query = Some(WorkflowQuery {
245
- query_type: "query-type".to_string(),
246
- query_args: Some(b"hi".into()),
247
- header: None,
248
- });
249
- pr.history = Some(History { events: vec![] });
250
- pr
251
- },
252
- ]);
234
+ let tasks = VecDeque::from(vec![hist_to_poll_resp(&t, wfid.to_owned(), 1.into()), {
235
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
236
+ pr.query = Some(WorkflowQuery {
237
+ query_type: "query-type".to_string(),
238
+ query_args: Some(b"hi".into()),
239
+ header: None,
240
+ });
241
+ pr.history = Some(History { events: vec![] });
242
+ pr
243
+ }]);
253
244
  let mut mock = MockPollCfg::from_resp_batches(wfid, t, tasks, mock_workflow_client());
254
245
  mock.num_expected_legacy_query_resps = 1;
255
246
  let mut mock = build_mock_pollers(mock);
@@ -292,12 +283,7 @@ async fn query_failure_because_nondeterminism(#[values(true, false)] legacy: boo
292
283
  let wfid = "fake_wf_id";
293
284
  let t = canned_histories::single_timer("1");
294
285
  let tasks = [{
295
- let mut pr = hist_to_poll_resp(
296
- &t,
297
- wfid.to_owned(),
298
- ResponseType::AllHistory,
299
- TEST_Q.to_string(),
300
- );
286
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory);
301
287
  if legacy {
302
288
  pr.query = Some(WorkflowQuery {
303
289
  query_type: "query-type".to_string(),
@@ -356,12 +342,7 @@ async fn legacy_query_after_complete(#[values(false, true)] full_history: bool)
356
342
  t
357
343
  };
358
344
  let query_with_hist_task = {
359
- let mut pr = hist_to_poll_resp(
360
- &t,
361
- wfid.to_owned(),
362
- ResponseType::AllHistory,
363
- TEST_Q.to_string(),
364
- );
345
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory);
365
346
  pr.query = Some(WorkflowQuery {
366
347
  query_type: "query-type".to_string(),
367
348
  query_args: Some(b"hi".into()),
@@ -375,15 +356,7 @@ async fn legacy_query_after_complete(#[values(false, true)] full_history: bool)
375
356
  let mut tasks = if full_history {
376
357
  vec![]
377
358
  } else {
378
- vec![
379
- hist_to_poll_resp(
380
- &t,
381
- wfid.to_owned(),
382
- ResponseType::AllHistory,
383
- TEST_Q.to_string(),
384
- )
385
- .resp,
386
- ]
359
+ vec![hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory).resp]
387
360
  };
388
361
  tasks.extend([query_with_hist_task.clone(), query_with_hist_task]);
389
362
 
@@ -456,29 +429,14 @@ async fn query_cache_miss_causes_page_fetch_dont_reply_wft_too_early(
456
429
  QueryHists::Empty => {
457
430
  // Create a no-history poll response. This happens to be easiest to do by just ripping
458
431
  // out the history after making a normal one.
459
- let mut pr = hist_to_poll_resp(
460
- &t,
461
- wfid.to_owned(),
462
- ResponseType::AllHistory,
463
- TEST_Q.to_string(),
464
- );
432
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory);
465
433
  pr.history = Some(Default::default());
466
434
  pr
467
435
  }
468
- QueryHists::Full => hist_to_poll_resp(
469
- &t,
470
- wfid.to_owned(),
471
- ResponseType::AllHistory,
472
- TEST_Q.to_string(),
473
- ),
436
+ QueryHists::Full => hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::AllHistory),
474
437
  QueryHists::Partial => {
475
438
  // Create a partial task
476
- hist_to_poll_resp(
477
- &t,
478
- wfid.to_owned(),
479
- ResponseType::OneTask(2),
480
- TEST_Q.to_string(),
481
- )
439
+ hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2))
482
440
  }
483
441
  };
484
442
  pr.queries = HashMap::new();
@@ -579,12 +537,7 @@ async fn query_replay_with_continue_as_new_doesnt_reply_empty_command() {
579
537
  let wfid = "fake_wf_id";
580
538
  let t = canned_histories::single_timer("1");
581
539
  let query_with_hist_task = {
582
- let mut pr = hist_to_poll_resp(
583
- &t,
584
- wfid.to_owned(),
585
- ResponseType::ToTaskNum(1),
586
- TEST_Q.to_string(),
587
- );
540
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(1));
588
541
  pr.queries = HashMap::new();
589
542
  pr.queries.insert(
590
543
  "the-query".to_string(),
@@ -682,7 +635,7 @@ async fn legacy_query_response_gets_not_found_not_fatal() {
682
635
  let wfid = "fake_wf_id";
683
636
  let t = canned_histories::single_timer("1");
684
637
  let tasks = [{
685
- let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string());
638
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
686
639
  pr.query = Some(WorkflowQuery {
687
640
  query_type: "query-type".to_string(),
688
641
  query_args: Some(b"hi".into()),
@@ -734,3 +687,208 @@ async fn legacy_query_response_gets_not_found_not_fatal() {
734
687
 
735
688
  core.shutdown().await;
736
689
  }
690
+
691
+ #[tokio::test]
692
+ async fn new_query_fail() {
693
+ let wfid = "fake_wf_id";
694
+ let t = canned_histories::single_timer("1");
695
+ let tasks = VecDeque::from(vec![{
696
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), 1.into());
697
+ pr.queries = HashMap::new();
698
+ pr.queries.insert(
699
+ "q1".to_string(),
700
+ WorkflowQuery {
701
+ query_type: "query-type".to_string(),
702
+ query_args: Some(b"hi".into()),
703
+ header: Default::default(),
704
+ },
705
+ );
706
+ pr
707
+ }]);
708
+ let mut mock_client = mock_workflow_client();
709
+ mock_client
710
+ .expect_complete_workflow_task()
711
+ .times(1)
712
+ .returning(|resp| {
713
+ // Verify there is a failed query response along w/ start timer cmd
714
+ assert_eq!(resp.commands.len(), 1);
715
+ assert_matches!(
716
+ resp.query_responses.as_slice(),
717
+ &[QueryResult {
718
+ variant: Some(query_result::Variant::Failed(_)),
719
+ ..
720
+ }]
721
+ );
722
+ Ok(RespondWorkflowTaskCompletedResponse::default())
723
+ });
724
+
725
+ let mut mock = single_hist_mock_sg(wfid, t, tasks, mock_client, true);
726
+ mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
727
+ let core = mock_worker(mock);
728
+
729
+ let task = core.poll_workflow_activation().await.unwrap();
730
+ assert_matches!(
731
+ task.jobs[0],
732
+ WorkflowActivationJob {
733
+ variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
734
+ }
735
+ );
736
+
737
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
738
+ task.run_id,
739
+ start_timer_cmd(1, Duration::from_secs(1)),
740
+ ))
741
+ .await
742
+ .unwrap();
743
+ let task = core.poll_workflow_activation().await.unwrap();
744
+ assert_matches!(
745
+ task.jobs[0],
746
+ WorkflowActivationJob {
747
+ variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
748
+ }
749
+ );
750
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
751
+ task.run_id,
752
+ QueryResult {
753
+ query_id: "q1".to_string(),
754
+ variant: Some(query_result::Variant::Failed("ahhh".into())),
755
+ }
756
+ .into(),
757
+ ))
758
+ .await
759
+ .unwrap();
760
+ }
761
+
762
+ /// This test verifies that if we get a task with a legacy query in it while in the middle of
763
+ /// processing some local-only work (in this case, resolving an activity as soon as it was
764
+ /// cancelled) that we do not combine the legacy query with the resolve job.
765
+ #[tokio::test]
766
+ async fn legacy_query_combined_with_timer_fire_repro() {
767
+ let wfid = "fake_wf_id";
768
+ let mut t = TestHistoryBuilder::default();
769
+ t.add_by_type(EventType::WorkflowExecutionStarted);
770
+ t.add_full_wf_task();
771
+ let scheduled_event_id = t.add_activity_task_scheduled("1");
772
+ let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
773
+ t.add_timer_fired(timer_started_event_id, "1".to_string());
774
+ t.add_full_wf_task();
775
+ t.add(
776
+ EventType::ActivityTaskCancelRequested,
777
+ history_event::Attributes::ActivityTaskCancelRequestedEventAttributes(
778
+ ActivityTaskCancelRequestedEventAttributes {
779
+ scheduled_event_id,
780
+ ..Default::default()
781
+ },
782
+ ),
783
+ );
784
+
785
+ let tasks = [
786
+ hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(1)),
787
+ {
788
+ // One task is super important here - as we need to look like we hit the cache
789
+ // to apply this query right away
790
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2));
791
+ pr.queries = HashMap::new();
792
+ pr.queries.insert(
793
+ "the-query".to_string(),
794
+ WorkflowQuery {
795
+ query_type: "query-type".to_string(),
796
+ query_args: Some(b"hi".into()),
797
+ header: None,
798
+ },
799
+ );
800
+ pr
801
+ },
802
+ {
803
+ let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(2));
804
+ // Strip history, we need to look like we hit the cache for a legacy query
805
+ pr.history = Some(History { events: vec![] });
806
+ pr.query = Some(WorkflowQuery {
807
+ query_type: "query-type".to_string(),
808
+ query_args: Some(b"hi".into()),
809
+ header: None,
810
+ });
811
+ pr
812
+ },
813
+ ];
814
+ let mut mock = mock_workflow_client();
815
+ mock.expect_respond_legacy_query()
816
+ .times(1)
817
+ .returning(move |_, _| Ok(Default::default()));
818
+ let mut mock = single_hist_mock_sg(wfid, t, tasks, mock, true);
819
+ mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
820
+ let core = mock_worker(mock);
821
+
822
+ let task = core.poll_workflow_activation().await.unwrap();
823
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
824
+ task.run_id,
825
+ vec![
826
+ schedule_activity_cmd(
827
+ 1,
828
+ "whatever",
829
+ "1",
830
+ ActivityCancellationType::TryCancel,
831
+ Duration::from_secs(60),
832
+ Duration::from_secs(60),
833
+ ),
834
+ start_timer_cmd(1, Duration::from_secs(1)),
835
+ ],
836
+ ))
837
+ .await
838
+ .unwrap();
839
+
840
+ let task = core.poll_workflow_activation().await.unwrap();
841
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
842
+ task.run_id,
843
+ vec![
844
+ RequestCancelActivity { seq: 1 }.into(),
845
+ QueryResult {
846
+ query_id: "the-query".to_string(),
847
+ variant: Some(
848
+ QuerySuccess {
849
+ response: Some("whatever".into()),
850
+ }
851
+ .into(),
852
+ ),
853
+ }
854
+ .into(),
855
+ ],
856
+ ))
857
+ .await
858
+ .unwrap();
859
+
860
+ // First should get the activity resolve
861
+ let task = core.poll_workflow_activation().await.unwrap();
862
+ assert_matches!(
863
+ task.jobs.as_slice(),
864
+ [WorkflowActivationJob {
865
+ variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
866
+ }]
867
+ );
868
+ core.complete_execution(&task.run_id).await;
869
+
870
+ // Then the query
871
+ let task = core.poll_workflow_activation().await.unwrap();
872
+ assert_matches!(
873
+ task.jobs.as_slice(),
874
+ [WorkflowActivationJob {
875
+ variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
876
+ }]
877
+ );
878
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
879
+ task.run_id,
880
+ QueryResult {
881
+ query_id: LEGACY_QUERY_ID.to_string(),
882
+ variant: Some(
883
+ QuerySuccess {
884
+ response: Some("whatever".into()),
885
+ }
886
+ .into(),
887
+ ),
888
+ }
889
+ .into(),
890
+ ))
891
+ .await
892
+ .unwrap();
893
+ core.shutdown().await;
894
+ }
@@ -24,7 +24,7 @@ use tokio::sync::{watch, Barrier};
24
24
  #[tokio::test]
25
25
  async fn after_shutdown_of_worker_get_shutdown_err() {
26
26
  let t = canned_histories::single_timer("1");
27
- let worker = build_fake_worker("fake_wf_id", t, &[1]);
27
+ let worker = build_fake_worker("fake_wf_id", t, [1]);
28
28
  let res = worker.poll_workflow_activation().await.unwrap();
29
29
  assert_eq!(res.jobs.len(), 1);
30
30
  let run_id = res.run_id;
@@ -53,7 +53,7 @@ async fn after_shutdown_of_worker_get_shutdown_err() {
53
53
  #[tokio::test]
54
54
  async fn shutdown_worker_can_complete_pending_activation() {
55
55
  let t = canned_histories::single_timer("1");
56
- let worker = build_fake_worker("fake_wf_id", t, &[2]);
56
+ let worker = build_fake_worker("fake_wf_id", t, [2]);
57
57
  let res = worker.poll_workflow_activation().await.unwrap();
58
58
  assert_eq!(res.jobs.len(), 1);
59
59
  // Complete the timer, will queue PA
@@ -107,7 +107,7 @@ async fn timer_then_cancel_req_then_timer_then_cancelled() {
107
107
  async fn immediate_cancel() {
108
108
  let wfid = "fake_wf_id";
109
109
  let t = canned_histories::immediate_wf_cancel();
110
- let core = build_fake_worker(wfid, t, &[1]);
110
+ let core = build_fake_worker(wfid, t, [1]);
111
111
 
112
112
  poll_and_reply(
113
113
  &core,
@@ -7,7 +7,6 @@ use crate::{
7
7
  mock_worker, poll_and_reply, poll_and_reply_clears_outstanding_evicts, single_hist_mock_sg,
8
8
  test_worker_cfg, FakeWfResponses, MockPollCfg, MocksHolder, ResponseType,
9
9
  WorkflowCachingPolicy::{self, AfterEveryReply, NonSticky},
10
- TEST_Q,
11
10
  },
12
11
  worker::client::mocks::{mock_manual_workflow_client, mock_workflow_client},
13
12
  Worker,
@@ -652,7 +651,7 @@ async fn workflow_update_random_seed_on_workflow_reset() {
652
651
  timer_1_id.to_string().as_str(),
653
652
  new_run_id,
654
653
  );
655
- let core = build_fake_worker(wfid, t, &[2]);
654
+ let core = build_fake_worker(wfid, t, [2]);
656
655
 
657
656
  poll_and_reply(
658
657
  &core,
@@ -706,7 +705,7 @@ async fn cancel_timer_before_sent_wf_bridge() {
706
705
  t.add_full_wf_task();
707
706
  t.add_workflow_execution_completed();
708
707
 
709
- let core = build_fake_worker(wfid, t, &[1]);
708
+ let core = build_fake_worker(wfid, t, [1]);
710
709
 
711
710
  poll_and_reply(
712
711
  &core,
@@ -1037,7 +1036,6 @@ async fn lots_of_workflows() {
1037
1036
  let completed_count = Arc::new(Semaphore::new(0));
1038
1037
  let killer = async {
1039
1038
  let _ = completed_count.acquire_many(total_wfs).await.unwrap();
1040
- dbg!("Shutdown initted");
1041
1039
  worker.initiate_shutdown();
1042
1040
  };
1043
1041
  let poller = fanout_tasks(5, |_| {
@@ -1122,7 +1120,7 @@ async fn complete_after_eviction() {
1122
1120
  let t = canned_histories::single_timer("1");
1123
1121
  let mut mock = mock_workflow_client();
1124
1122
  mock.expect_complete_workflow_task().times(0);
1125
- let mock = single_hist_mock_sg(wfid, t, &[2], mock, true);
1123
+ let mock = single_hist_mock_sg(wfid, t, [2], mock, true);
1126
1124
  let core = mock_worker(mock);
1127
1125
 
1128
1126
  let activation = core.poll_workflow_activation().await.unwrap();
@@ -1164,7 +1162,7 @@ async fn sends_appropriate_sticky_task_queue_responses() {
1164
1162
  .times(1)
1165
1163
  .returning(|_| Ok(Default::default()));
1166
1164
  mock.expect_complete_workflow_task().times(0);
1167
- let mut mock = single_hist_mock_sg(wfid, t, &[1], mock, false);
1165
+ let mut mock = single_hist_mock_sg(wfid, t, [1], mock, false);
1168
1166
  mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
1169
1167
  let core = mock_worker(mock);
1170
1168
 
@@ -1182,7 +1180,7 @@ async fn sends_appropriate_sticky_task_queue_responses() {
1182
1180
  async fn new_server_work_while_eviction_outstanding_doesnt_overwrite_activation() {
1183
1181
  let wfid = "fake_wf_id";
1184
1182
  let t = canned_histories::single_timer("1");
1185
- let mock = single_hist_mock_sg(wfid, t, &[1, 2], mock_workflow_client(), false);
1183
+ let mock = single_hist_mock_sg(wfid, t, [1, 2], mock_workflow_client(), false);
1186
1184
  let taskmap = mock.outstanding_task_map.clone().unwrap();
1187
1185
  let core = mock_worker(mock);
1188
1186
 
@@ -1224,7 +1222,7 @@ async fn buffered_work_drained_on_shutdown() {
1224
1222
  t.add_workflow_task_scheduled_and_started();
1225
1223
  // Need to build the first response before adding the timeout events b/c otherwise the history
1226
1224
  // builder will include them in the first task
1227
- let resp_1 = hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()).resp;
1225
+ let resp_1 = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()).resp;
1228
1226
  t.add_workflow_task_timed_out();
1229
1227
  t.add_full_wf_task();
1230
1228
  let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
@@ -1242,10 +1240,7 @@ async fn buffered_work_drained_on_shutdown() {
1242
1240
  // Extend the task list with the now timeout-included version of the task. We add a bunch of
1243
1241
  // them because the poll loop will spin while new tasks are available and it is buffering them
1244
1242
  tasks.extend(
1245
- std::iter::repeat_with(|| {
1246
- hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()).resp
1247
- })
1248
- .take(50),
1243
+ std::iter::repeat_with(|| hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp).take(50),
1249
1244
  );
1250
1245
  let mut mock = mock_workflow_client();
1251
1246
  mock.expect_complete_workflow_task()
@@ -1448,7 +1443,7 @@ async fn tries_cancel_of_completed_activity() {
1448
1443
  t.add_workflow_task_scheduled_and_started();
1449
1444
 
1450
1445
  let mock = mock_workflow_client();
1451
- let mut mock = single_hist_mock_sg("fake_wf_id", t, &[1, 2], mock, true);
1446
+ let mut mock = single_hist_mock_sg("fake_wf_id", t, [1, 2], mock, true);
1452
1447
  mock.worker_cfg(|cfg| cfg.max_cached_workflows = 1);
1453
1448
  let core = mock_worker(mock);
1454
1449
 
@@ -1658,10 +1653,9 @@ async fn tasks_from_completion_are_delivered() {
1658
1653
 
1659
1654
  let mut mock = mock_workflow_client();
1660
1655
  let complete_resp = RespondWorkflowTaskCompletedResponse {
1661
- workflow_task: Some(
1662
- hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()).resp,
1663
- ),
1656
+ workflow_task: Some(hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp),
1664
1657
  activity_tasks: vec![],
1658
+ reset_history_event_id: 0,
1665
1659
  };
1666
1660
  mock.expect_complete_workflow_task()
1667
1661
  .times(1)
@@ -1829,7 +1823,7 @@ async fn eviction_waits_until_replay_finished() {
1829
1823
  let wfid = "fake_wf_id";
1830
1824
  let t = canned_histories::long_sequential_timers(3);
1831
1825
  let mock = mock_workflow_client();
1832
- let mock = single_hist_mock_sg(wfid, t, &[3], mock, true);
1826
+ let mock = single_hist_mock_sg(wfid, t, [3], mock, true);
1833
1827
  let core = mock_worker(mock);
1834
1828
 
1835
1829
  let activation = core.poll_workflow_activation().await.unwrap();
@@ -1890,7 +1884,7 @@ async fn autocompletes_wft_no_work() {
1890
1884
  t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
1891
1885
  t.add_full_wf_task();
1892
1886
  let mock = mock_workflow_client();
1893
- let mut mock = single_hist_mock_sg(wfid, t, &[1, 2, 3, 4], mock, true);
1887
+ let mut mock = single_hist_mock_sg(wfid, t, [1, 2, 3, 4], mock, true);
1894
1888
  mock.worker_cfg(|w| w.max_cached_workflows = 1);
1895
1889
  let core = mock_worker(mock);
1896
1890
 
@@ -1951,8 +1945,7 @@ async fn no_race_acquiring_permits() {
1951
1945
  .expect_poll_workflow_task()
1952
1946
  .returning(move |_, _| {
1953
1947
  let t = canned_histories::single_timer("1");
1954
- let poll_resp =
1955
- hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()).resp;
1948
+ let poll_resp = hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp;
1956
1949
  async move {
1957
1950
  task_barr.wait().await;
1958
1951
  Ok(poll_resp.clone())
@@ -2031,13 +2024,7 @@ async fn continue_as_new_preserves_some_values() {
2031
2024
  mock_client
2032
2025
  .expect_poll_workflow_task()
2033
2026
  .returning(move |_, _| {
2034
- Ok(hist_to_poll_resp(
2035
- &hist,
2036
- wfid.to_owned(),
2037
- ResponseType::AllHistory,
2038
- TEST_Q.to_string(),
2039
- )
2040
- .resp)
2027
+ Ok(hist_to_poll_resp(&hist, wfid.to_owned(), ResponseType::AllHistory).resp)
2041
2028
  });
2042
2029
  mock_client
2043
2030
  .expect_complete_workflow_task()
@@ -2068,3 +2055,36 @@ async fn continue_as_new_preserves_some_values() {
2068
2055
  .await
2069
2056
  .unwrap();
2070
2057
  }
2058
+
2059
+ #[rstest]
2060
+ #[tokio::test]
2061
+ async fn ignorable_events_are_ok(#[values(true, false)] attribs_unset: bool) {
2062
+ let mut t = TestHistoryBuilder::default();
2063
+ t.add_by_type(EventType::WorkflowExecutionStarted);
2064
+ let id = t.add_get_event_id(
2065
+ EventType::Unspecified,
2066
+ Some(
2067
+ history_event::Attributes::WorkflowPropertiesModifiedExternallyEventAttributes(
2068
+ Default::default(),
2069
+ ),
2070
+ ),
2071
+ );
2072
+ t.modify_event(id, |e| e.worker_may_ignore = true);
2073
+ if attribs_unset {
2074
+ t.modify_event(id, |e| {
2075
+ e.event_type = EventType::WorkflowPropertiesModifiedExternally as i32;
2076
+ e.attributes = None;
2077
+ });
2078
+ }
2079
+ t.add_workflow_task_scheduled_and_started();
2080
+
2081
+ let mock = mock_workflow_client();
2082
+ let mock = single_hist_mock_sg("wheee", t, [ResponseType::AllHistory], mock, true);
2083
+ let core = mock_worker(mock);
2084
+
2085
+ let act = core.poll_workflow_activation().await.unwrap();
2086
+ assert_matches!(
2087
+ act.jobs[0].variant,
2088
+ Some(workflow_activation_job::Variant::StartWorkflow(_))
2089
+ );
2090
+ }