temporalio 0.1.1 → 0.3.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 (628) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/Cargo.lock +4324 -0
  4. data/Cargo.toml +25 -0
  5. data/Gemfile +20 -0
  6. data/LICENSE +16 -15
  7. data/README.md +985 -183
  8. data/Rakefile +101 -0
  9. data/ext/Cargo.toml +26 -0
  10. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  11. data/lib/temporalio/activity/context.rb +86 -78
  12. data/lib/temporalio/activity/definition.rb +175 -0
  13. data/lib/temporalio/activity/info.rb +44 -47
  14. data/lib/temporalio/activity.rb +8 -81
  15. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  16. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  17. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  18. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +126 -0
  19. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  20. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  21. data/lib/temporalio/api/cloud/identity/v1/message.rb +41 -0
  22. data/lib/temporalio/api/cloud/namespace/v1/message.rb +42 -0
  23. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  24. data/lib/temporalio/api/cloud/operation/v1/message.rb +28 -0
  25. data/lib/temporalio/api/cloud/region/v1/message.rb +24 -0
  26. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  27. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  28. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  29. data/lib/temporalio/api/command/v1/message.rb +46 -0
  30. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  31. data/lib/temporalio/api/common/v1/message.rb +47 -0
  32. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  33. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  34. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  35. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  36. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  37. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  38. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  39. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  40. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  41. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  42. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  43. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  44. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  45. data/lib/temporalio/api/export/v1/message.rb +24 -0
  46. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  47. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  48. data/lib/temporalio/api/history/v1/message.rb +90 -0
  49. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  50. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  51. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  52. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  53. data/lib/temporalio/api/operatorservice.rb +3 -0
  54. data/lib/temporalio/api/payload_visitor.rb +1513 -0
  55. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  56. data/lib/temporalio/api/query/v1/message.rb +27 -0
  57. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  58. data/lib/temporalio/api/schedule/v1/message.rb +43 -0
  59. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  60. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  61. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  62. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  63. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  64. data/lib/{gen/temporal/api/testservice/v1/request_response_pb.rb → temporalio/api/testservice/v1/request_response.rb} +6 -24
  65. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  66. data/lib/temporalio/api/update/v1/message.rb +33 -0
  67. data/lib/temporalio/api/version/v1/message.rb +26 -0
  68. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  69. data/lib/temporalio/api/workflowservice/v1/request_response.rb +204 -0
  70. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  71. data/lib/temporalio/api/workflowservice.rb +3 -0
  72. data/lib/temporalio/api.rb +14 -0
  73. data/lib/temporalio/cancellation.rb +170 -0
  74. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  75. data/lib/temporalio/client/async_activity_handle.rb +85 -0
  76. data/lib/temporalio/client/connection/cloud_service.rb +726 -0
  77. data/lib/temporalio/client/connection/operator_service.rb +201 -0
  78. data/lib/temporalio/client/connection/service.rb +42 -0
  79. data/lib/temporalio/client/connection/test_service.rb +111 -0
  80. data/lib/temporalio/client/connection/workflow_service.rb +1041 -0
  81. data/lib/temporalio/client/connection.rb +316 -0
  82. data/lib/temporalio/client/interceptor.rb +416 -0
  83. data/lib/temporalio/client/schedule.rb +967 -0
  84. data/lib/temporalio/client/schedule_handle.rb +126 -0
  85. data/lib/temporalio/client/workflow_execution.rb +100 -0
  86. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  87. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  88. data/lib/temporalio/client/workflow_handle.rb +326 -180
  89. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  90. data/lib/temporalio/client/workflow_update_handle.rb +65 -0
  91. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  92. data/lib/temporalio/client.rb +447 -94
  93. data/lib/temporalio/common_enums.rb +41 -0
  94. data/lib/temporalio/converters/data_converter.rb +99 -0
  95. data/lib/temporalio/converters/failure_converter.rb +202 -0
  96. data/lib/temporalio/converters/payload_codec.rb +26 -0
  97. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  98. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  99. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  100. data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
  101. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  102. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  103. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  104. data/lib/temporalio/converters/payload_converter.rb +71 -0
  105. data/lib/temporalio/converters/raw_value.rb +20 -0
  106. data/lib/temporalio/converters.rb +9 -0
  107. data/lib/temporalio/error/failure.rb +119 -94
  108. data/lib/temporalio/error.rb +155 -0
  109. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  110. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  111. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  112. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  113. data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
  114. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  115. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  116. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
  117. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
  118. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  119. data/lib/temporalio/internal/bridge/api.rb +3 -0
  120. data/lib/temporalio/internal/bridge/client.rb +95 -0
  121. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  122. data/lib/temporalio/internal/bridge/testing.rb +66 -0
  123. data/lib/temporalio/internal/bridge/worker.rb +85 -0
  124. data/lib/temporalio/internal/bridge.rb +36 -0
  125. data/lib/temporalio/internal/client/implementation.rb +700 -0
  126. data/lib/temporalio/internal/metric.rb +122 -0
  127. data/lib/temporalio/internal/proto_utils.rb +133 -0
  128. data/lib/temporalio/internal/worker/activity_worker.rb +373 -0
  129. data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
  130. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  131. data/lib/temporalio/internal/worker/workflow_instance/context.rb +329 -0
  132. data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
  133. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  134. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  135. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  136. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  137. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  138. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  139. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
  140. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  141. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  142. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
  143. data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
  144. data/lib/temporalio/internal/worker/workflow_worker.rb +196 -0
  145. data/lib/temporalio/internal.rb +7 -0
  146. data/lib/temporalio/metric.rb +109 -0
  147. data/lib/temporalio/retry_policy.rb +55 -73
  148. data/lib/temporalio/runtime.rb +302 -13
  149. data/lib/temporalio/scoped_logger.rb +96 -0
  150. data/lib/temporalio/search_attributes.rb +343 -0
  151. data/lib/temporalio/testing/activity_environment.rb +132 -0
  152. data/lib/temporalio/testing/workflow_environment.rb +345 -74
  153. data/lib/temporalio/testing.rb +4 -169
  154. data/lib/temporalio/version.rb +3 -1
  155. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  156. data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
  157. data/lib/temporalio/worker/activity_executor.rb +55 -0
  158. data/lib/temporalio/worker/interceptor.rb +362 -0
  159. data/lib/temporalio/worker/thread_pool.rb +237 -0
  160. data/lib/temporalio/worker/tuner.rb +151 -0
  161. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
  162. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  163. data/lib/temporalio/worker.rb +554 -161
  164. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  165. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  166. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  167. data/lib/temporalio/workflow/definition.rb +566 -0
  168. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  169. data/lib/temporalio/workflow/future.rb +117 -104
  170. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  171. data/lib/temporalio/workflow/info.rb +63 -57
  172. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  173. data/lib/temporalio/workflow/update_info.rb +20 -0
  174. data/lib/temporalio/workflow.rb +523 -0
  175. data/lib/temporalio/workflow_history.rb +22 -0
  176. data/lib/temporalio.rb +6 -7
  177. data/temporalio.gemspec +20 -39
  178. metadata +171 -710
  179. data/bridge/Cargo.lock +0 -2997
  180. data/bridge/Cargo.toml +0 -29
  181. data/bridge/sdk-core/ARCHITECTURE.md +0 -76
  182. data/bridge/sdk-core/Cargo.toml +0 -2
  183. data/bridge/sdk-core/LICENSE.txt +0 -23
  184. data/bridge/sdk-core/README.md +0 -117
  185. data/bridge/sdk-core/arch_docs/diagrams/README.md +0 -10
  186. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +0 -40
  187. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  188. data/bridge/sdk-core/arch_docs/sticky_queues.md +0 -51
  189. data/bridge/sdk-core/client/Cargo.toml +0 -40
  190. data/bridge/sdk-core/client/LICENSE.txt +0 -23
  191. data/bridge/sdk-core/client/src/lib.rs +0 -1462
  192. data/bridge/sdk-core/client/src/metrics.rs +0 -174
  193. data/bridge/sdk-core/client/src/raw.rs +0 -932
  194. data/bridge/sdk-core/client/src/retry.rs +0 -763
  195. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +0 -185
  196. data/bridge/sdk-core/core/Cargo.toml +0 -129
  197. data/bridge/sdk-core/core/LICENSE.txt +0 -23
  198. data/bridge/sdk-core/core/benches/workflow_replay.rs +0 -76
  199. data/bridge/sdk-core/core/src/abstractions.rs +0 -355
  200. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +0 -1049
  201. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +0 -221
  202. data/bridge/sdk-core/core/src/core_tests/determinism.rs +0 -270
  203. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +0 -1046
  204. data/bridge/sdk-core/core/src/core_tests/mod.rs +0 -100
  205. data/bridge/sdk-core/core/src/core_tests/queries.rs +0 -893
  206. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +0 -65
  207. data/bridge/sdk-core/core/src/core_tests/workers.rs +0 -257
  208. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +0 -124
  209. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +0 -2433
  210. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +0 -609
  211. data/bridge/sdk-core/core/src/internal_flags.rs +0 -136
  212. data/bridge/sdk-core/core/src/lib.rs +0 -289
  213. data/bridge/sdk-core/core/src/pollers/mod.rs +0 -54
  214. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +0 -297
  215. data/bridge/sdk-core/core/src/protosext/mod.rs +0 -428
  216. data/bridge/sdk-core/core/src/replay/mod.rs +0 -215
  217. data/bridge/sdk-core/core/src/retry_logic.rs +0 -202
  218. data/bridge/sdk-core/core/src/telemetry/log_export.rs +0 -190
  219. data/bridge/sdk-core/core/src/telemetry/metrics.rs +0 -462
  220. data/bridge/sdk-core/core/src/telemetry/mod.rs +0 -423
  221. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +0 -83
  222. data/bridge/sdk-core/core/src/test_help/mod.rs +0 -939
  223. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +0 -536
  224. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +0 -89
  225. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +0 -1278
  226. data/bridge/sdk-core/core/src/worker/activities.rs +0 -557
  227. data/bridge/sdk-core/core/src/worker/client/mocks.rs +0 -107
  228. data/bridge/sdk-core/core/src/worker/client.rs +0 -389
  229. data/bridge/sdk-core/core/src/worker/mod.rs +0 -677
  230. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +0 -35
  231. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +0 -99
  232. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +0 -1111
  233. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +0 -964
  234. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -294
  235. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -168
  236. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +0 -918
  237. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -137
  238. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -158
  239. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -130
  240. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -1525
  241. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -324
  242. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -179
  243. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -659
  244. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -439
  245. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +0 -435
  246. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +0 -175
  247. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +0 -249
  248. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +0 -85
  249. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +0 -1280
  250. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +0 -269
  251. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +0 -213
  252. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +0 -1305
  253. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +0 -1276
  254. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +0 -128
  255. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +0 -125
  256. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +0 -85
  257. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  258. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  259. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +0 -715
  260. data/bridge/sdk-core/core-api/Cargo.toml +0 -33
  261. data/bridge/sdk-core/core-api/LICENSE.txt +0 -23
  262. data/bridge/sdk-core/core-api/src/errors.rs +0 -62
  263. data/bridge/sdk-core/core-api/src/lib.rs +0 -113
  264. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -141
  265. data/bridge/sdk-core/core-api/src/worker.rs +0 -161
  266. data/bridge/sdk-core/etc/deps.svg +0 -162
  267. data/bridge/sdk-core/etc/dynamic-config.yaml +0 -2
  268. data/bridge/sdk-core/etc/otel-collector-config.yaml +0 -36
  269. data/bridge/sdk-core/etc/prometheus.yaml +0 -6
  270. data/bridge/sdk-core/etc/regen-depgraph.sh +0 -5
  271. data/bridge/sdk-core/fsm/Cargo.toml +0 -18
  272. data/bridge/sdk-core/fsm/LICENSE.txt +0 -23
  273. data/bridge/sdk-core/fsm/README.md +0 -3
  274. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +0 -27
  275. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +0 -23
  276. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +0 -650
  277. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +0 -8
  278. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +0 -18
  279. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +0 -12
  280. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +0 -41
  281. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +0 -14
  282. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +0 -11
  283. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +0 -32
  284. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +0 -31
  285. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +0 -46
  286. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +0 -29
  287. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +0 -12
  288. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +0 -32
  289. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +0 -18
  290. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +0 -5
  291. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +0 -11
  292. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +0 -5
  293. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +0 -11
  294. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +0 -5
  295. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +0 -14
  296. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +0 -23
  297. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +0 -254
  298. data/bridge/sdk-core/fsm/src/lib.rs +0 -2
  299. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  300. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  301. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  302. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  303. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  304. data/bridge/sdk-core/integ-with-otel.sh +0 -7
  305. data/bridge/sdk-core/protos/api_upstream/README.md +0 -9
  306. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +0 -40
  307. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -9
  308. data/bridge/sdk-core/protos/api_upstream/build/go.mod +0 -7
  309. data/bridge/sdk-core/protos/api_upstream/build/go.sum +0 -5
  310. data/bridge/sdk-core/protos/api_upstream/build/tools.go +0 -29
  311. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +0 -141
  312. data/bridge/sdk-core/protos/api_upstream/go.mod +0 -6
  313. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +0 -89
  314. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +0 -248
  315. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +0 -123
  316. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -47
  317. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +0 -52
  318. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +0 -56
  319. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +0 -170
  320. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +0 -123
  321. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +0 -51
  322. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +0 -50
  323. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +0 -41
  324. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +0 -60
  325. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -59
  326. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +0 -56
  327. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +0 -122
  328. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +0 -108
  329. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +0 -114
  330. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +0 -56
  331. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +0 -787
  332. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +0 -99
  333. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +0 -124
  334. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -80
  335. data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +0 -57
  336. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +0 -61
  337. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +0 -55
  338. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +0 -379
  339. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +0 -63
  340. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +0 -108
  341. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +0 -111
  342. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +0 -59
  343. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +0 -146
  344. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +0 -1199
  345. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +0 -415
  346. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +0 -63
  347. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +0 -79
  348. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +0 -80
  349. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -78
  350. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -16
  351. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +0 -31
  352. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +0 -31
  353. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +0 -270
  354. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +0 -305
  355. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -35
  356. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +0 -38
  357. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +0 -13
  358. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +0 -141
  359. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -63
  360. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -90
  361. data/bridge/sdk-core/rustfmt.toml +0 -1
  362. data/bridge/sdk-core/sdk/Cargo.toml +0 -48
  363. data/bridge/sdk-core/sdk/LICENSE.txt +0 -23
  364. data/bridge/sdk-core/sdk/src/activity_context.rs +0 -230
  365. data/bridge/sdk-core/sdk/src/app_data.rs +0 -37
  366. data/bridge/sdk-core/sdk/src/interceptors.rs +0 -50
  367. data/bridge/sdk-core/sdk/src/lib.rs +0 -861
  368. data/bridge/sdk-core/sdk/src/payload_converter.rs +0 -11
  369. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +0 -295
  370. data/bridge/sdk-core/sdk/src/workflow_context.rs +0 -694
  371. data/bridge/sdk-core/sdk/src/workflow_future.rs +0 -500
  372. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +0 -33
  373. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +0 -23
  374. data/bridge/sdk-core/sdk-core-protos/build.rs +0 -142
  375. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +0 -7
  376. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +0 -557
  377. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +0 -234
  378. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +0 -2088
  379. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +0 -48
  380. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +0 -14
  381. data/bridge/sdk-core/test-utils/Cargo.toml +0 -38
  382. data/bridge/sdk-core/test-utils/src/canned_histories.rs +0 -1389
  383. data/bridge/sdk-core/test-utils/src/histfetch.rs +0 -28
  384. data/bridge/sdk-core/test-utils/src/lib.rs +0 -709
  385. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  386. data/bridge/sdk-core/test-utils/src/workflows.rs +0 -29
  387. data/bridge/sdk-core/tests/fuzzy_workflow.rs +0 -130
  388. data/bridge/sdk-core/tests/heavy_tests.rs +0 -265
  389. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +0 -36
  390. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +0 -150
  391. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +0 -223
  392. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +0 -239
  393. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -90
  394. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +0 -314
  395. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +0 -151
  396. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +0 -902
  397. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
  398. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +0 -60
  399. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +0 -51
  400. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +0 -51
  401. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +0 -64
  402. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -47
  403. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +0 -669
  404. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +0 -54
  405. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +0 -92
  406. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +0 -228
  407. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +0 -94
  408. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +0 -171
  409. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +0 -85
  410. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +0 -120
  411. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +0 -77
  412. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +0 -596
  413. data/bridge/sdk-core/tests/main.rs +0 -103
  414. data/bridge/sdk-core/tests/runner.rs +0 -132
  415. data/bridge/sdk-core/tests/wf_input_replay.rs +0 -32
  416. data/bridge/src/connection.rs +0 -202
  417. data/bridge/src/lib.rs +0 -494
  418. data/bridge/src/runtime.rs +0 -54
  419. data/bridge/src/test_server.rs +0 -153
  420. data/bridge/src/worker.rs +0 -197
  421. data/ext/Rakefile +0 -9
  422. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +0 -14
  423. data/lib/gen/temporal/api/batch/v1/message_pb.rb +0 -50
  424. data/lib/gen/temporal/api/command/v1/message_pb.rb +0 -160
  425. data/lib/gen/temporal/api/common/v1/message_pb.rb +0 -73
  426. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +0 -33
  427. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +0 -37
  428. data/lib/gen/temporal/api/enums/v1/common_pb.rb +0 -42
  429. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +0 -68
  430. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +0 -79
  431. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +0 -37
  432. data/lib/gen/temporal/api/enums/v1/query_pb.rb +0 -31
  433. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +0 -24
  434. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +0 -28
  435. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +0 -30
  436. data/lib/gen/temporal/api/enums/v1/update_pb.rb +0 -25
  437. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +0 -89
  438. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +0 -84
  439. data/lib/gen/temporal/api/failure/v1/message_pb.rb +0 -83
  440. data/lib/gen/temporal/api/filter/v1/message_pb.rb +0 -40
  441. data/lib/gen/temporal/api/history/v1/message_pb.rb +0 -498
  442. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +0 -64
  443. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +0 -88
  444. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +0 -20
  445. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +0 -30
  446. data/lib/gen/temporal/api/query/v1/message_pb.rb +0 -38
  447. data/lib/gen/temporal/api/replication/v1/message_pb.rb +0 -37
  448. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +0 -149
  449. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +0 -23
  450. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +0 -73
  451. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +0 -21
  452. data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -72
  453. data/lib/gen/temporal/api/version/v1/message_pb.rb +0 -41
  454. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +0 -111
  455. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +0 -798
  456. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +0 -20
  457. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +0 -62
  458. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +0 -61
  459. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +0 -61
  460. data/lib/gen/temporal/sdk/core/common/common_pb.rb +0 -26
  461. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +0 -40
  462. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +0 -31
  463. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +0 -171
  464. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +0 -200
  465. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +0 -41
  466. data/lib/temporalio/bridge/connect_options.rb +0 -15
  467. data/lib/temporalio/bridge/error.rb +0 -8
  468. data/lib/temporalio/bridge/retry_config.rb +0 -24
  469. data/lib/temporalio/bridge/tls_options.rb +0 -19
  470. data/lib/temporalio/bridge.rb +0 -14
  471. data/lib/temporalio/client/implementation.rb +0 -340
  472. data/lib/temporalio/connection/retry_config.rb +0 -44
  473. data/lib/temporalio/connection/service.rb +0 -20
  474. data/lib/temporalio/connection/test_service.rb +0 -92
  475. data/lib/temporalio/connection/tls_options.rb +0 -51
  476. data/lib/temporalio/connection/workflow_service.rb +0 -731
  477. data/lib/temporalio/connection.rb +0 -86
  478. data/lib/temporalio/data_converter.rb +0 -191
  479. data/lib/temporalio/error/workflow_failure.rb +0 -19
  480. data/lib/temporalio/errors.rb +0 -40
  481. data/lib/temporalio/failure_converter/base.rb +0 -26
  482. data/lib/temporalio/failure_converter/basic.rb +0 -319
  483. data/lib/temporalio/failure_converter.rb +0 -7
  484. data/lib/temporalio/interceptor/activity_inbound.rb +0 -22
  485. data/lib/temporalio/interceptor/activity_outbound.rb +0 -24
  486. data/lib/temporalio/interceptor/chain.rb +0 -28
  487. data/lib/temporalio/interceptor/client.rb +0 -127
  488. data/lib/temporalio/interceptor.rb +0 -22
  489. data/lib/temporalio/payload_codec/base.rb +0 -32
  490. data/lib/temporalio/payload_converter/base.rb +0 -24
  491. data/lib/temporalio/payload_converter/bytes.rb +0 -27
  492. data/lib/temporalio/payload_converter/composite.rb +0 -49
  493. data/lib/temporalio/payload_converter/encoding_base.rb +0 -35
  494. data/lib/temporalio/payload_converter/json.rb +0 -26
  495. data/lib/temporalio/payload_converter/nil.rb +0 -26
  496. data/lib/temporalio/payload_converter.rb +0 -14
  497. data/lib/temporalio/retry_state.rb +0 -35
  498. data/lib/temporalio/testing/time_skipping_handle.rb +0 -32
  499. data/lib/temporalio/testing/time_skipping_interceptor.rb +0 -23
  500. data/lib/temporalio/timeout_type.rb +0 -29
  501. data/lib/temporalio/worker/activity_runner.rb +0 -114
  502. data/lib/temporalio/worker/activity_worker.rb +0 -164
  503. data/lib/temporalio/worker/reactor.rb +0 -46
  504. data/lib/temporalio/worker/runner.rb +0 -63
  505. data/lib/temporalio/worker/sync_worker.rb +0 -124
  506. data/lib/temporalio/worker/thread_pool_executor.rb +0 -51
  507. data/lib/temporalio/workflow/async.rb +0 -46
  508. data/lib/temporalio/workflow/execution_info.rb +0 -54
  509. data/lib/temporalio/workflow/execution_status.rb +0 -36
  510. data/lib/temporalio/workflow/id_reuse_policy.rb +0 -36
  511. data/lib/temporalio/workflow/query_reject_condition.rb +0 -33
  512. data/lib/thermite_patch.rb +0 -33
  513. data/sig/async.rbs +0 -17
  514. data/sig/protobuf.rbs +0 -16
  515. data/sig/protos/dependencies/gogoproto/gogo.rbs +0 -914
  516. data/sig/protos/google/protobuf/any.rbs +0 -157
  517. data/sig/protos/google/protobuf/descriptor.rbs +0 -2825
  518. data/sig/protos/google/protobuf/duration.rbs +0 -114
  519. data/sig/protos/google/protobuf/empty.rbs +0 -36
  520. data/sig/protos/google/protobuf/timestamp.rbs +0 -145
  521. data/sig/protos/google/protobuf/wrappers.rbs +0 -358
  522. data/sig/protos/temporal/api/batch/v1/message.rbs +0 -300
  523. data/sig/protos/temporal/api/command/v1/message.rbs +0 -1399
  524. data/sig/protos/temporal/api/common/v1/message.rbs +0 -528
  525. data/sig/protos/temporal/api/enums/v1/batch_operation.rbs +0 -79
  526. data/sig/protos/temporal/api/enums/v1/command_type.rbs +0 -68
  527. data/sig/protos/temporal/api/enums/v1/common.rbs +0 -118
  528. data/sig/protos/temporal/api/enums/v1/event_type.rbs +0 -264
  529. data/sig/protos/temporal/api/enums/v1/failed_cause.rbs +0 -277
  530. data/sig/protos/temporal/api/enums/v1/namespace.rbs +0 -108
  531. data/sig/protos/temporal/api/enums/v1/query.rbs +0 -81
  532. data/sig/protos/temporal/api/enums/v1/reset.rbs +0 -44
  533. data/sig/protos/temporal/api/enums/v1/schedule.rbs +0 -72
  534. data/sig/protos/temporal/api/enums/v1/task_queue.rbs +0 -92
  535. data/sig/protos/temporal/api/enums/v1/update.rbs +0 -64
  536. data/sig/protos/temporal/api/enums/v1/workflow.rbs +0 -371
  537. data/sig/protos/temporal/api/errordetails/v1/message.rbs +0 -551
  538. data/sig/protos/temporal/api/failure/v1/message.rbs +0 -581
  539. data/sig/protos/temporal/api/filter/v1/message.rbs +0 -171
  540. data/sig/protos/temporal/api/history/v1/message.rbs +0 -4609
  541. data/sig/protos/temporal/api/namespace/v1/message.rbs +0 -410
  542. data/sig/protos/temporal/api/operatorservice/v1/request_response.rbs +0 -643
  543. data/sig/protos/temporal/api/operatorservice/v1/service.rbs +0 -17
  544. data/sig/protos/temporal/api/protocol/v1/message.rbs +0 -84
  545. data/sig/protos/temporal/api/query/v1/message.rbs +0 -182
  546. data/sig/protos/temporal/api/replication/v1/message.rbs +0 -148
  547. data/sig/protos/temporal/api/schedule/v1/message.rbs +0 -1488
  548. data/sig/protos/temporal/api/sdk/v1/task_complete_metadata.rbs +0 -110
  549. data/sig/protos/temporal/api/taskqueue/v1/message.rbs +0 -486
  550. data/sig/protos/temporal/api/testservice/v1/request_response.rbs +0 -249
  551. data/sig/protos/temporal/api/testservice/v1/service.rbs +0 -15
  552. data/sig/protos/temporal/api/update/v1/message.rbs +0 -489
  553. data/sig/protos/temporal/api/version/v1/message.rbs +0 -184
  554. data/sig/protos/temporal/api/workflow/v1/message.rbs +0 -824
  555. data/sig/protos/temporal/api/workflowservice/v1/request_response.rbs +0 -7250
  556. data/sig/protos/temporal/api/workflowservice/v1/service.rbs +0 -22
  557. data/sig/protos/temporal/sdk/core/activity_result/activity_result.rbs +0 -380
  558. data/sig/protos/temporal/sdk/core/activity_task/activity_task.rbs +0 -386
  559. data/sig/protos/temporal/sdk/core/child_workflow/child_workflow.rbs +0 -323
  560. data/sig/protos/temporal/sdk/core/common/common.rbs +0 -62
  561. data/sig/protos/temporal/sdk/core/core_interface.rbs +0 -101
  562. data/sig/protos/temporal/sdk/core/external_data/external_data.rbs +0 -119
  563. data/sig/protos/temporal/sdk/core/workflow_activation/workflow_activation.rbs +0 -1473
  564. data/sig/protos/temporal/sdk/core/workflow_commands/workflow_commands.rbs +0 -1784
  565. data/sig/protos/temporal/sdk/core/workflow_completion/workflow_completion.rbs +0 -180
  566. data/sig/ruby.rbs +0 -12
  567. data/sig/temporalio/activity/context.rbs +0 -29
  568. data/sig/temporalio/activity/info.rbs +0 -43
  569. data/sig/temporalio/activity.rbs +0 -19
  570. data/sig/temporalio/bridge/connect_options.rbs +0 -19
  571. data/sig/temporalio/bridge/error.rbs +0 -8
  572. data/sig/temporalio/bridge/retry_config.rbs +0 -21
  573. data/sig/temporalio/bridge/tls_options.rbs +0 -17
  574. data/sig/temporalio/bridge.rbs +0 -71
  575. data/sig/temporalio/client/implementation.rbs +0 -38
  576. data/sig/temporalio/client/workflow_handle.rbs +0 -41
  577. data/sig/temporalio/client.rbs +0 -35
  578. data/sig/temporalio/connection/retry_config.rbs +0 -37
  579. data/sig/temporalio/connection/service.rbs +0 -14
  580. data/sig/temporalio/connection/test_service.rbs +0 -13
  581. data/sig/temporalio/connection/tls_options.rbs +0 -43
  582. data/sig/temporalio/connection/workflow_service.rbs +0 -48
  583. data/sig/temporalio/connection.rbs +0 -30
  584. data/sig/temporalio/data_converter.rbs +0 -35
  585. data/sig/temporalio/error/failure.rbs +0 -121
  586. data/sig/temporalio/error/workflow_failure.rbs +0 -9
  587. data/sig/temporalio/errors.rbs +0 -36
  588. data/sig/temporalio/failure_converter/base.rbs +0 -12
  589. data/sig/temporalio/failure_converter/basic.rbs +0 -86
  590. data/sig/temporalio/failure_converter.rbs +0 -5
  591. data/sig/temporalio/interceptor/activity_inbound.rbs +0 -21
  592. data/sig/temporalio/interceptor/activity_outbound.rbs +0 -10
  593. data/sig/temporalio/interceptor/chain.rbs +0 -24
  594. data/sig/temporalio/interceptor/client.rbs +0 -148
  595. data/sig/temporalio/interceptor.rbs +0 -6
  596. data/sig/temporalio/payload_codec/base.rbs +0 -12
  597. data/sig/temporalio/payload_converter/base.rbs +0 -12
  598. data/sig/temporalio/payload_converter/bytes.rbs +0 -9
  599. data/sig/temporalio/payload_converter/composite.rbs +0 -19
  600. data/sig/temporalio/payload_converter/encoding_base.rbs +0 -14
  601. data/sig/temporalio/payload_converter/json.rbs +0 -9
  602. data/sig/temporalio/payload_converter/nil.rbs +0 -9
  603. data/sig/temporalio/payload_converter.rbs +0 -5
  604. data/sig/temporalio/retry_policy.rbs +0 -25
  605. data/sig/temporalio/retry_state.rbs +0 -20
  606. data/sig/temporalio/runtime.rbs +0 -12
  607. data/sig/temporalio/testing/time_skipping_handle.rbs +0 -15
  608. data/sig/temporalio/testing/time_skipping_interceptor.rbs +0 -13
  609. data/sig/temporalio/testing/workflow_environment.rbs +0 -22
  610. data/sig/temporalio/testing.rbs +0 -35
  611. data/sig/temporalio/timeout_type.rbs +0 -15
  612. data/sig/temporalio/version.rbs +0 -3
  613. data/sig/temporalio/worker/activity_runner.rbs +0 -35
  614. data/sig/temporalio/worker/activity_worker.rbs +0 -44
  615. data/sig/temporalio/worker/reactor.rbs +0 -22
  616. data/sig/temporalio/worker/runner.rbs +0 -21
  617. data/sig/temporalio/worker/sync_worker.rbs +0 -23
  618. data/sig/temporalio/worker/thread_pool_executor.rbs +0 -23
  619. data/sig/temporalio/worker.rbs +0 -46
  620. data/sig/temporalio/workflow/async.rbs +0 -9
  621. data/sig/temporalio/workflow/execution_info.rbs +0 -55
  622. data/sig/temporalio/workflow/execution_status.rbs +0 -21
  623. data/sig/temporalio/workflow/future.rbs +0 -40
  624. data/sig/temporalio/workflow/id_reuse_policy.rbs +0 -15
  625. data/sig/temporalio/workflow/info.rbs +0 -55
  626. data/sig/temporalio/workflow/query_reject_condition.rbs +0 -14
  627. data/sig/temporalio.rbs +0 -2
  628. data/sig/thermite_patch.rbs +0 -15
@@ -1,2433 +0,0 @@
1
- use crate::{
2
- advance_fut, job_assert,
3
- replay::TestHistoryBuilder,
4
- test_help::{
5
- build_fake_worker, build_mock_pollers, build_multihist_mock_sg, canned_histories,
6
- gen_assert_and_fail, gen_assert_and_reply, hist_to_poll_resp, mock_sdk, mock_sdk_cfg,
7
- mock_worker, poll_and_reply, poll_and_reply_clears_outstanding_evicts, single_hist_mock_sg,
8
- test_worker_cfg, FakeWfResponses, MockPollCfg, MocksHolder, ResponseType,
9
- WorkflowCachingPolicy::{self, AfterEveryReply, NonSticky},
10
- },
11
- worker::client::mocks::{mock_manual_workflow_client, mock_workflow_client},
12
- Worker,
13
- };
14
- use futures::{stream, FutureExt};
15
- use rstest::{fixture, rstest};
16
- use std::{
17
- collections::{HashMap, VecDeque},
18
- sync::{
19
- atomic::{AtomicBool, AtomicU64, Ordering},
20
- Arc,
21
- },
22
- time::Duration,
23
- };
24
- use temporal_sdk::{ActivityOptions, CancellableFuture, WfContext};
25
- use temporal_sdk_core_api::{errors::PollWfError, Worker as WorkerTrait};
26
- use temporal_sdk_core_protos::{
27
- coresdk::{
28
- activity_result::{self as ar, activity_resolution, ActivityResolution},
29
- workflow_activation::{
30
- remove_from_cache::EvictionReason, workflow_activation_job, FireTimer, ResolveActivity,
31
- StartWorkflow, UpdateRandomSeed, WorkflowActivationJob,
32
- },
33
- workflow_commands::{
34
- ActivityCancellationType, CancelTimer, CompleteWorkflowExecution,
35
- ContinueAsNewWorkflowExecution, FailWorkflowExecution, RequestCancelActivity,
36
- ScheduleActivity,
37
- },
38
- workflow_completion::WorkflowActivationCompletion,
39
- },
40
- default_act_sched, default_wes_attribs,
41
- temporal::api::{
42
- command::v1::command::Attributes,
43
- common::v1::{Payload, RetryPolicy},
44
- enums::v1::{EventType, WorkflowTaskFailedCause},
45
- failure::v1::Failure,
46
- history::v1::{
47
- history_event, TimerFiredEventAttributes,
48
- WorkflowPropertiesModifiedExternallyEventAttributes,
49
- },
50
- workflowservice::v1::{
51
- GetWorkflowExecutionHistoryResponse, RespondWorkflowTaskCompletedResponse,
52
- },
53
- },
54
- DEFAULT_ACTIVITY_TYPE, DEFAULT_WORKFLOW_TYPE,
55
- };
56
- use temporal_sdk_core_test_utils::{
57
- fanout_tasks, schedule_activity_cmd, start_timer_cmd, WorkerTestHelpers,
58
- };
59
- use tokio::{
60
- join,
61
- sync::{Barrier, Semaphore},
62
- };
63
-
64
- #[fixture(hist_batches = &[])]
65
- fn single_timer_setup(hist_batches: &'static [usize]) -> Worker {
66
- let wfid = "fake_wf_id";
67
-
68
- let t = canned_histories::single_timer("1");
69
- build_fake_worker(wfid, t, hist_batches)
70
- }
71
-
72
- #[fixture(hist_batches = &[])]
73
- fn single_activity_setup(hist_batches: &'static [usize]) -> Worker {
74
- let wfid = "fake_wf_id";
75
-
76
- let t = canned_histories::single_activity("fake_activity");
77
- build_fake_worker(wfid, t, hist_batches)
78
- }
79
-
80
- #[fixture(hist_batches = &[])]
81
- fn single_activity_failure_setup(hist_batches: &'static [usize]) -> Worker {
82
- let wfid = "fake_wf_id";
83
-
84
- let t = canned_histories::single_failed_activity("fake_activity");
85
- build_fake_worker(wfid, t, hist_batches)
86
- }
87
-
88
- #[rstest]
89
- #[case::incremental(single_timer_setup(&[1, 2]), NonSticky)]
90
- #[case::replay(single_timer_setup(&[2]), NonSticky)]
91
- #[case::incremental_evict(single_timer_setup(&[1, 2]), AfterEveryReply)]
92
- #[case::replay_evict(single_timer_setup(&[2]), AfterEveryReply)]
93
- #[tokio::test]
94
- async fn single_timer(#[case] worker: Worker, #[case] evict: WorkflowCachingPolicy) {
95
- poll_and_reply(
96
- &worker,
97
- evict,
98
- &[
99
- gen_assert_and_reply(
100
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
101
- vec![start_timer_cmd(1, Duration::from_secs(1))],
102
- ),
103
- gen_assert_and_reply(
104
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
105
- vec![CompleteWorkflowExecution { result: None }.into()],
106
- ),
107
- ],
108
- )
109
- .await;
110
- }
111
-
112
- #[rstest(worker,
113
- case::incremental(single_activity_setup(&[1, 2])),
114
- case::incremental_activity_failure(single_activity_failure_setup(&[1, 2])),
115
- case::replay(single_activity_setup(&[2])),
116
- case::replay_activity_failure(single_activity_failure_setup(&[2]))
117
- )]
118
- #[tokio::test]
119
- async fn single_activity_completion(worker: Worker) {
120
- poll_and_reply(
121
- &worker,
122
- NonSticky,
123
- &[
124
- gen_assert_and_reply(
125
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
126
- vec![ScheduleActivity {
127
- activity_id: "fake_activity".to_string(),
128
- ..default_act_sched()
129
- }
130
- .into()],
131
- ),
132
- gen_assert_and_reply(
133
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(_)),
134
- vec![CompleteWorkflowExecution { result: None }.into()],
135
- ),
136
- ],
137
- )
138
- .await;
139
- }
140
-
141
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
142
- #[tokio::test]
143
- async fn parallel_timer_test_across_wf_bridge(hist_batches: &'static [usize]) {
144
- let wfid = "fake_wf_id";
145
- let timer_1_id = 1;
146
- let timer_2_id = 2;
147
-
148
- let t = canned_histories::parallel_timer(
149
- timer_1_id.to_string().as_str(),
150
- timer_2_id.to_string().as_str(),
151
- );
152
- let core = build_fake_worker(wfid, t, hist_batches);
153
-
154
- poll_and_reply(
155
- &core,
156
- NonSticky,
157
- &[
158
- gen_assert_and_reply(
159
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
160
- vec![
161
- start_timer_cmd(timer_1_id, Duration::from_secs(1)),
162
- start_timer_cmd(timer_2_id, Duration::from_secs(1)),
163
- ],
164
- ),
165
- gen_assert_and_reply(
166
- &|res| {
167
- assert_matches!(
168
- res.jobs.as_slice(),
169
- [
170
- WorkflowActivationJob {
171
- variant: Some(workflow_activation_job::Variant::FireTimer(
172
- FireTimer { seq: t1_id }
173
- )),
174
- },
175
- WorkflowActivationJob {
176
- variant: Some(workflow_activation_job::Variant::FireTimer(
177
- FireTimer { seq: t2_id }
178
- )),
179
- }
180
- ] => {
181
- assert_eq!(t1_id, &timer_1_id);
182
- assert_eq!(t2_id, &timer_2_id);
183
- }
184
- );
185
- },
186
- vec![CompleteWorkflowExecution { result: None }.into()],
187
- ),
188
- ],
189
- )
190
- .await;
191
- }
192
-
193
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
194
- #[tokio::test]
195
- async fn timer_cancel(hist_batches: &'static [usize]) {
196
- let wfid = "fake_wf_id";
197
- let timer_id = 1;
198
- let cancel_timer_id = 2;
199
-
200
- let t = canned_histories::cancel_timer(
201
- timer_id.to_string().as_str(),
202
- cancel_timer_id.to_string().as_str(),
203
- );
204
- let core = build_fake_worker(wfid, t, hist_batches);
205
-
206
- poll_and_reply(
207
- &core,
208
- NonSticky,
209
- &[
210
- gen_assert_and_reply(
211
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
212
- vec![
213
- start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
214
- start_timer_cmd(timer_id, Duration::from_secs(1)),
215
- ],
216
- ),
217
- gen_assert_and_reply(
218
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
219
- vec![
220
- CancelTimer {
221
- seq: cancel_timer_id,
222
- }
223
- .into(),
224
- CompleteWorkflowExecution { result: None }.into(),
225
- ],
226
- ),
227
- ],
228
- )
229
- .await;
230
- }
231
-
232
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
233
- #[tokio::test]
234
- async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usize]) {
235
- let wfid = "fake_wf_id";
236
- let activity_seq = 1;
237
- let activity_id = "fake_activity";
238
- let signal_id = "signal";
239
-
240
- let t = canned_histories::cancel_scheduled_activity(activity_id, signal_id);
241
- let core = build_fake_worker(wfid, t, hist_batches);
242
-
243
- poll_and_reply(
244
- &core,
245
- NonSticky,
246
- &[
247
- gen_assert_and_reply(
248
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
249
- vec![ScheduleActivity {
250
- seq: activity_seq,
251
- activity_id: activity_id.to_string(),
252
- cancellation_type: ActivityCancellationType::TryCancel as i32,
253
- ..default_act_sched()
254
- }
255
- .into()],
256
- ),
257
- gen_assert_and_reply(
258
- &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
259
- vec![RequestCancelActivity { seq: activity_seq }.into()],
260
- ),
261
- // Activity is getting resolved right away as we are in the TryCancel mode.
262
- gen_assert_and_reply(
263
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(_)),
264
- vec![CompleteWorkflowExecution { result: None }.into()],
265
- ),
266
- ],
267
- )
268
- .await;
269
- }
270
-
271
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
272
- #[tokio::test]
273
- async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
274
- let wfid = "fake_wf_id";
275
- let activity_seq = 1;
276
- let activity_id = "fake_activity";
277
-
278
- let t = canned_histories::scheduled_activity_timeout(activity_id);
279
- let core = build_fake_worker(wfid, t, hist_batches);
280
- poll_and_reply(
281
- &core,
282
- NonSticky,
283
- &[
284
- gen_assert_and_reply(
285
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
286
- vec![ScheduleActivity {
287
- seq: activity_seq,
288
- activity_id: activity_id.to_string(),
289
- ..default_act_sched()
290
- }
291
- .into()],
292
- ),
293
- // Activity is getting resolved right away as it has been timed out.
294
- gen_assert_and_reply(
295
- &|res| {
296
- assert_matches!(
297
- res.jobs.as_slice(),
298
- [
299
- WorkflowActivationJob {
300
- variant: Some(workflow_activation_job::Variant::ResolveActivity(
301
- ResolveActivity {
302
- seq,
303
- result: Some(ActivityResolution {
304
- status: Some(activity_resolution::Status::Failed(ar::Failure {
305
- failure: Some(failure)
306
- })),
307
- })
308
- }
309
- )),
310
- }
311
- ] => {
312
- assert_eq!(failure.message, "Activity task timed out".to_string());
313
- assert_eq!(*seq, activity_seq);
314
- }
315
- );
316
- },
317
- vec![CompleteWorkflowExecution { result: None }.into()],
318
- ),
319
- ],
320
- )
321
- .await;
322
- }
323
-
324
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
325
- #[tokio::test]
326
- async fn started_activity_timeout(hist_batches: &'static [usize]) {
327
- let wfid = "fake_wf_id";
328
- let activity_seq = 1;
329
-
330
- let t = canned_histories::started_activity_timeout(activity_seq.to_string().as_str());
331
- let core = build_fake_worker(wfid, t, hist_batches);
332
-
333
- poll_and_reply(
334
- &core,
335
- NonSticky,
336
- &[
337
- gen_assert_and_reply(
338
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
339
- vec![ScheduleActivity {
340
- seq: activity_seq,
341
- activity_id: activity_seq.to_string(),
342
- ..default_act_sched()
343
- }
344
- .into()],
345
- ),
346
- // Activity is getting resolved right away as it has been timed out.
347
- gen_assert_and_reply(
348
- &|res| {
349
- assert_matches!(
350
- res.jobs.as_slice(),
351
- [
352
- WorkflowActivationJob {
353
- variant: Some(workflow_activation_job::Variant::ResolveActivity(
354
- ResolveActivity {
355
- seq,
356
- result: Some(ActivityResolution {
357
- status: Some(activity_resolution::Status::Failed(ar::Failure {
358
- failure: Some(failure)
359
- })),
360
- })
361
- }
362
- )),
363
- }
364
- ] => {
365
- assert_eq!(failure.message, "Activity task timed out".to_string());
366
- assert_eq!(*seq, activity_seq);
367
- }
368
- );
369
- },
370
- vec![CompleteWorkflowExecution { result: None }.into()],
371
- ),
372
- ],
373
- )
374
- .await;
375
- }
376
-
377
- #[rstest(hist_batches, case::incremental(&[1, 3]), case::replay(&[3]))]
378
- #[tokio::test]
379
- async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
380
- let wfid = "fake_wf_id";
381
- let activity_seq = 0;
382
- let activity_id = "fake_activity";
383
- let signal_id = "signal";
384
-
385
- let t = canned_histories::scheduled_cancelled_activity_timeout(activity_id, signal_id);
386
- let core = build_fake_worker(wfid, t, hist_batches);
387
-
388
- poll_and_reply(
389
- &core,
390
- NonSticky,
391
- &[
392
- gen_assert_and_reply(
393
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
394
- vec![ScheduleActivity {
395
- seq: activity_seq,
396
- activity_id: activity_id.to_string(),
397
- ..default_act_sched()
398
- }
399
- .into()],
400
- ),
401
- gen_assert_and_reply(
402
- &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
403
- vec![RequestCancelActivity { seq: activity_seq }.into()],
404
- ),
405
- // Activity is resolved right away as it has timed out.
406
- gen_assert_and_reply(
407
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(
408
- ResolveActivity {
409
- seq: _,
410
- result: Some(ActivityResolution {
411
- status: Some(activity_resolution::Status::Cancelled(..)),
412
- })
413
- }
414
- )),
415
- vec![CompleteWorkflowExecution { result: None }.into()],
416
- ),
417
- ],
418
- )
419
- .await;
420
- }
421
-
422
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
423
- #[tokio::test]
424
- async fn scheduled_activity_cancellation_abandon(hist_batches: &'static [usize]) {
425
- let wfid = "fake_wf_id";
426
- let activity_id = 1;
427
- let signal_id = "signal";
428
-
429
- let t = canned_histories::cancel_scheduled_activity_abandon(
430
- activity_id.to_string().as_str(),
431
- signal_id,
432
- );
433
- let core = build_fake_worker(wfid, t, hist_batches);
434
-
435
- verify_activity_cancellation(&core, activity_id, ActivityCancellationType::Abandon).await;
436
- }
437
-
438
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
439
- #[tokio::test]
440
- async fn started_activity_cancellation_abandon(hist_batches: &'static [usize]) {
441
- let wfid = "fake_wf_id";
442
- let activity_id = 1;
443
- let signal_id = "signal";
444
-
445
- let t = canned_histories::cancel_started_activity_abandon(
446
- activity_id.to_string().as_str(),
447
- signal_id,
448
- );
449
- let core = build_fake_worker(wfid, t, hist_batches);
450
-
451
- verify_activity_cancellation(&core, activity_id, ActivityCancellationType::Abandon).await;
452
- }
453
-
454
- #[rstest(hist_batches, case::incremental(&[1, 2, 3, 4]), case::replay(&[4]))]
455
- #[tokio::test]
456
- async fn abandoned_activities_ignore_start_and_complete(hist_batches: &'static [usize]) {
457
- let wfid = "fake_wf_id";
458
- let wf_type = DEFAULT_WORKFLOW_TYPE;
459
- let activity_id = "1";
460
-
461
- let mut t = TestHistoryBuilder::default();
462
- t.add_by_type(EventType::WorkflowExecutionStarted);
463
- t.add_full_wf_task();
464
- let act_scheduled_event_id = t.add_activity_task_scheduled(activity_id);
465
- let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
466
- t.add_timer_fired(timer_started_event_id, "1".to_string());
467
- t.add_full_wf_task();
468
- let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
469
- let act_started_event_id = t.add_activity_task_started(act_scheduled_event_id);
470
- t.add_activity_task_completed(
471
- act_scheduled_event_id,
472
- act_started_event_id,
473
- Default::default(),
474
- );
475
- t.add_full_wf_task();
476
- t.add_timer_fired(timer_started_event_id, "2".to_string());
477
- t.add_full_wf_task();
478
- t.add_workflow_execution_completed();
479
- let mock = mock_workflow_client();
480
- let mut worker = mock_sdk(MockPollCfg::from_resp_batches(wfid, t, hist_batches, mock));
481
-
482
- worker.register_wf(wf_type.to_owned(), |ctx: WfContext| async move {
483
- let act_fut = ctx.activity(ActivityOptions {
484
- activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
485
- start_to_close_timeout: Some(Duration::from_secs(5)),
486
- cancellation_type: ActivityCancellationType::Abandon,
487
- ..Default::default()
488
- });
489
- ctx.timer(Duration::from_secs(1)).await;
490
- act_fut.cancel(&ctx);
491
- ctx.timer(Duration::from_secs(3)).await;
492
- act_fut.await;
493
- Ok(().into())
494
- });
495
- worker
496
- .submit_wf(wfid, wf_type, vec![], Default::default())
497
- .await
498
- .unwrap();
499
- worker.run_until_done().await.unwrap();
500
- }
501
-
502
- #[rstest(hist_batches, case::incremental(&[1, 3]), case::replay(&[3]))]
503
- #[tokio::test]
504
- async fn scheduled_activity_cancellation_try_cancel_task_canceled(hist_batches: &'static [usize]) {
505
- let wfid = "fake_wf_id";
506
- let activity_id = 1;
507
- let signal_id = "signal";
508
-
509
- let t = canned_histories::cancel_scheduled_activity_with_activity_task_cancel(
510
- activity_id.to_string().as_str(),
511
- signal_id,
512
- );
513
- let core = build_fake_worker(wfid, t, hist_batches);
514
-
515
- verify_activity_cancellation(&core, activity_id, ActivityCancellationType::TryCancel).await;
516
- }
517
-
518
- #[rstest(hist_batches, case::incremental(&[1, 3]), case::replay(&[3]))]
519
- #[tokio::test]
520
- async fn started_activity_cancellation_try_cancel_task_canceled(hist_batches: &'static [usize]) {
521
- let wfid = "fake_wf_id";
522
- let activity_id = 1;
523
- let signal_id = "signal";
524
-
525
- let t = canned_histories::cancel_started_activity_with_activity_task_cancel(
526
- activity_id.to_string().as_str(),
527
- signal_id,
528
- );
529
- let core = build_fake_worker(wfid, t, hist_batches);
530
-
531
- verify_activity_cancellation(&core, activity_id, ActivityCancellationType::TryCancel).await;
532
- }
533
-
534
- /// Verification for try cancel & abandon histories
535
- async fn verify_activity_cancellation(
536
- worker: &Worker,
537
- activity_seq: u32,
538
- cancel_type: ActivityCancellationType,
539
- ) {
540
- poll_and_reply(
541
- worker,
542
- NonSticky,
543
- &[
544
- gen_assert_and_reply(
545
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
546
- vec![ScheduleActivity {
547
- seq: activity_seq,
548
- activity_id: activity_seq.to_string(),
549
- cancellation_type: cancel_type as i32,
550
- ..default_act_sched()
551
- }
552
- .into()],
553
- ),
554
- gen_assert_and_reply(
555
- &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
556
- vec![RequestCancelActivity { seq: activity_seq }.into()],
557
- ),
558
- // Activity should be resolved right away
559
- gen_assert_and_reply(
560
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(
561
- ResolveActivity {
562
- seq: _,
563
- result: Some(ActivityResolution {
564
- status: Some(activity_resolution::Status::Cancelled(..)),
565
- })
566
- }
567
- )),
568
- vec![CompleteWorkflowExecution { result: None }.into()],
569
- ),
570
- ],
571
- )
572
- .await;
573
- }
574
-
575
- #[rstest(hist_batches, case::incremental(&[1, 2, 3, 4]), case::replay(&[4]))]
576
- #[tokio::test]
577
- async fn scheduled_activity_cancellation_wait_for_cancellation(hist_batches: &'static [usize]) {
578
- let wfid = "fake_wf_id";
579
- let activity_id = 1;
580
- let signal_id = "signal";
581
-
582
- let t = canned_histories::cancel_scheduled_activity_with_signal_and_activity_task_cancel(
583
- activity_id.to_string().as_str(),
584
- signal_id,
585
- );
586
- let core = build_fake_worker(wfid, t, hist_batches);
587
-
588
- verify_activity_cancellation_wait_for_cancellation(activity_id, &core).await;
589
- }
590
-
591
- #[rstest(hist_batches, case::incremental(&[1, 2, 3, 4]), case::replay(&[4]))]
592
- #[tokio::test]
593
- async fn started_activity_cancellation_wait_for_cancellation(hist_batches: &'static [usize]) {
594
- let wfid = "fake_wf_id";
595
- let activity_id = 1;
596
- let signal_id = "signal";
597
-
598
- let t = canned_histories::cancel_started_activity_with_signal_and_activity_task_cancel(
599
- activity_id.to_string().as_str(),
600
- signal_id,
601
- );
602
- let core = build_fake_worker(wfid, t, hist_batches);
603
-
604
- verify_activity_cancellation_wait_for_cancellation(activity_id, &core).await;
605
- }
606
-
607
- async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, worker: &Worker) {
608
- poll_and_reply(
609
- worker,
610
- NonSticky,
611
- &[
612
- gen_assert_and_reply(
613
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
614
- vec![ScheduleActivity {
615
- seq: activity_id,
616
- activity_id: activity_id.to_string(),
617
- cancellation_type: ActivityCancellationType::WaitCancellationCompleted as i32,
618
- ..default_act_sched()
619
- }
620
- .into()],
621
- ),
622
- gen_assert_and_reply(
623
- &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
624
- vec![RequestCancelActivity { seq: activity_id }.into()],
625
- ),
626
- // Making sure that activity is not resolved until it's cancelled.
627
- gen_assert_and_reply(
628
- &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
629
- vec![],
630
- ),
631
- // Now ActivityTaskCanceled has been processed and activity can be resolved.
632
- gen_assert_and_reply(
633
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(
634
- ResolveActivity {
635
- seq: _,
636
- result: Some(ActivityResolution {
637
- status: Some(activity_resolution::Status::Cancelled(..)),
638
- })
639
- }
640
- )),
641
- vec![CompleteWorkflowExecution { result: None }.into()],
642
- ),
643
- ],
644
- )
645
- .await;
646
- }
647
-
648
- #[tokio::test]
649
- async fn workflow_update_random_seed_on_workflow_reset() {
650
- let wfid = "fake_wf_id";
651
- let new_run_id = "86E39A5F-AE31-4626-BDFE-398EE072D156";
652
- let timer_1_id = 1;
653
- let randomness_seed_from_start = AtomicU64::new(0);
654
-
655
- let t = canned_histories::workflow_fails_with_reset_after_timer(
656
- timer_1_id.to_string().as_str(),
657
- new_run_id,
658
- );
659
- let core = build_fake_worker(wfid, t, [2]);
660
-
661
- poll_and_reply(
662
- &core,
663
- NonSticky,
664
- &[
665
- gen_assert_and_reply(
666
- &|res| {
667
- assert_matches!(
668
- res.jobs.as_slice(),
669
- [WorkflowActivationJob {
670
- variant: Some(workflow_activation_job::Variant::StartWorkflow(
671
- StartWorkflow{randomness_seed, ..}
672
- )),
673
- }] => {
674
- randomness_seed_from_start.store(*randomness_seed, Ordering::SeqCst);
675
- }
676
- );
677
- },
678
- vec![start_timer_cmd(timer_1_id, Duration::from_secs(1))],
679
- ),
680
- gen_assert_and_reply(
681
- &|res| {
682
- assert_matches!(
683
- res.jobs.as_slice(),
684
- [WorkflowActivationJob {
685
- variant: Some(workflow_activation_job::Variant::FireTimer(_),),
686
- },
687
- WorkflowActivationJob {
688
- variant: Some(workflow_activation_job::Variant::UpdateRandomSeed(
689
- UpdateRandomSeed{randomness_seed})),
690
- }] => {
691
- assert_ne!(randomness_seed_from_start.load(Ordering::SeqCst),
692
- *randomness_seed);
693
- }
694
- );
695
- },
696
- vec![CompleteWorkflowExecution { result: None }.into()],
697
- ),
698
- ],
699
- )
700
- .await;
701
- }
702
-
703
- #[tokio::test]
704
- async fn cancel_timer_before_sent_wf_bridge() {
705
- let wfid = "fake_wf_id";
706
- let cancel_timer_id = 1;
707
-
708
- let mut t = TestHistoryBuilder::default();
709
- t.add_by_type(EventType::WorkflowExecutionStarted);
710
- t.add_full_wf_task();
711
- t.add_workflow_execution_completed();
712
-
713
- let core = build_fake_worker(wfid, t, [1]);
714
-
715
- poll_and_reply(
716
- &core,
717
- NonSticky,
718
- &[gen_assert_and_reply(
719
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
720
- vec![
721
- start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
722
- CancelTimer {
723
- seq: cancel_timer_id,
724
- }
725
- .into(),
726
- CompleteWorkflowExecution { result: None }.into(),
727
- ],
728
- )],
729
- )
730
- .await;
731
- }
732
-
733
- #[rstest]
734
- #[case::no_evict_inc(&[1, 2, 2], NonSticky)]
735
- #[case::no_evict(&[2, 2], NonSticky)]
736
- #[tokio::test]
737
- async fn complete_activation_with_failure(
738
- #[case] batches: &'static [usize],
739
- #[case] evict: WorkflowCachingPolicy,
740
- ) {
741
- let wfid = "fake_wf_id";
742
- let timer_id = 1;
743
-
744
- let hist =
745
- canned_histories::workflow_fails_with_failure_after_timer(timer_id.to_string().as_str());
746
- let mock_sg = build_multihist_mock_sg(
747
- vec![FakeWfResponses {
748
- wf_id: wfid.to_string(),
749
- hist,
750
- response_batches: batches.iter().map(Into::into).collect(),
751
- }],
752
- true,
753
- 1,
754
- );
755
- let core = mock_worker(mock_sg);
756
-
757
- poll_and_reply(
758
- &core,
759
- evict,
760
- &[
761
- gen_assert_and_reply(
762
- &|_| {},
763
- vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
764
- ),
765
- gen_assert_and_fail(&|_| {}),
766
- gen_assert_and_reply(
767
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
768
- vec![CompleteWorkflowExecution { result: None }.into()],
769
- ),
770
- ],
771
- )
772
- .await;
773
- core.shutdown().await;
774
- }
775
-
776
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
777
- #[tokio::test]
778
- async fn simple_timer_fail_wf_execution(hist_batches: &'static [usize]) {
779
- let wfid = "fake_wf_id";
780
- let timer_id = 1;
781
-
782
- let t = canned_histories::single_timer(timer_id.to_string().as_str());
783
- let core = build_fake_worker(wfid, t, hist_batches);
784
-
785
- poll_and_reply(
786
- &core,
787
- NonSticky,
788
- &[
789
- gen_assert_and_reply(
790
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
791
- vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
792
- ),
793
- gen_assert_and_reply(
794
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
795
- vec![FailWorkflowExecution {
796
- failure: Some(Failure {
797
- message: "I'm ded".to_string(),
798
- ..Default::default()
799
- }),
800
- }
801
- .into()],
802
- ),
803
- ],
804
- )
805
- .await;
806
- }
807
-
808
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
809
- #[tokio::test]
810
- async fn two_signals(hist_batches: &'static [usize]) {
811
- let wfid = "fake_wf_id";
812
-
813
- let t = canned_histories::two_signals("sig1", "sig2");
814
- let core = build_fake_worker(wfid, t, hist_batches);
815
-
816
- poll_and_reply(
817
- &core,
818
- NonSticky,
819
- &[
820
- gen_assert_and_reply(
821
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
822
- // Task is completed with no commands
823
- vec![],
824
- ),
825
- gen_assert_and_reply(
826
- &job_assert!(
827
- workflow_activation_job::Variant::SignalWorkflow(_),
828
- workflow_activation_job::Variant::SignalWorkflow(_)
829
- ),
830
- vec![],
831
- ),
832
- ],
833
- )
834
- .await;
835
- }
836
-
837
- #[tokio::test]
838
- async fn workflow_failures_only_reported_once() {
839
- let wfid = "fake_wf_id";
840
- let timer_1 = 1;
841
- let timer_2 = 2;
842
-
843
- let hist = canned_histories::workflow_fails_with_failure_two_different_points(
844
- timer_1.to_string().as_str(),
845
- timer_2.to_string().as_str(),
846
- );
847
- let response_batches = vec![
848
- 1, 2, // Start then first good reply
849
- 2, 2, 2, // Poll for every failure
850
- // Poll again after evicting after second good reply, then two more fails
851
- 3, 3, 3,
852
- ];
853
- let mocks = build_multihist_mock_sg(
854
- vec![FakeWfResponses {
855
- wf_id: wfid.to_string(),
856
- hist,
857
- response_batches: response_batches.into_iter().map(Into::into).collect(),
858
- }],
859
- true,
860
- // We should only call the server to say we failed twice (once after each success)
861
- 2,
862
- );
863
- let omap = mocks.outstanding_task_map.clone();
864
- let core = mock_worker(mocks);
865
-
866
- poll_and_reply_clears_outstanding_evicts(
867
- &core,
868
- omap,
869
- NonSticky,
870
- &[
871
- gen_assert_and_reply(
872
- &|_| {},
873
- vec![start_timer_cmd(timer_1, Duration::from_secs(1))],
874
- ),
875
- // Fail a few times in a row (only one of which should be reported)
876
- gen_assert_and_fail(&|_| {}),
877
- gen_assert_and_fail(&|_| {}),
878
- gen_assert_and_fail(&|_| {}),
879
- gen_assert_and_reply(
880
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
881
- vec![start_timer_cmd(timer_2, Duration::from_secs(1))],
882
- ),
883
- // Again (a new fail should be reported here)
884
- gen_assert_and_fail(&|_| {}),
885
- gen_assert_and_fail(&|_| {}),
886
- gen_assert_and_reply(
887
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
888
- vec![CompleteWorkflowExecution { result: None }.into()],
889
- ),
890
- ],
891
- )
892
- .await;
893
- }
894
-
895
- #[tokio::test]
896
- async fn max_wft_respected() {
897
- let total_wfs = 100;
898
- let wf_ids: Vec<_> = (0..total_wfs)
899
- .into_iter()
900
- .map(|i| format!("fake-wf-{i}"))
901
- .collect();
902
- let hists = wf_ids.iter().map(|wf_id| {
903
- let hist = canned_histories::single_timer("1");
904
- FakeWfResponses {
905
- wf_id: wf_id.to_string(),
906
- hist,
907
- response_batches: vec![1.into(), 2.into()],
908
- }
909
- });
910
- let mh = MockPollCfg::new(hists.into_iter().collect(), true, 0);
911
- let mut worker = mock_sdk_cfg(mh, |cfg| {
912
- cfg.max_cached_workflows = total_wfs as usize;
913
- cfg.max_outstanding_workflow_tasks = 1;
914
- });
915
- let active_count: &'static _ = Box::leak(Box::new(Semaphore::new(1)));
916
- worker.register_wf(DEFAULT_WORKFLOW_TYPE, move |ctx: WfContext| async move {
917
- drop(
918
- active_count
919
- .try_acquire()
920
- .expect("No multiple concurrent workflow tasks!"),
921
- );
922
- ctx.timer(Duration::from_secs(1)).await;
923
- Ok(().into())
924
- });
925
-
926
- for wf_id in wf_ids {
927
- worker
928
- .submit_wf(wf_id, DEFAULT_WORKFLOW_TYPE, vec![], Default::default())
929
- .await
930
- .unwrap();
931
- }
932
- worker.run_until_done().await.unwrap();
933
- }
934
-
935
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[3]))]
936
- #[tokio::test]
937
- async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
938
- let wfid = "fake_wf_id";
939
- let t = canned_histories::unsent_at_cancel_repro();
940
- let core = build_fake_worker(wfid, t, hist_batches);
941
- let activity_id = 1;
942
-
943
- poll_and_reply(
944
- &core,
945
- NonSticky,
946
- &[
947
- gen_assert_and_reply(
948
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
949
- // Start timer and activity
950
- vec![
951
- ScheduleActivity {
952
- seq: activity_id,
953
- activity_id: activity_id.to_string(),
954
- cancellation_type: ActivityCancellationType::TryCancel as i32,
955
- ..default_act_sched()
956
- }
957
- .into(),
958
- start_timer_cmd(1, Duration::from_secs(1)),
959
- ],
960
- ),
961
- gen_assert_and_reply(
962
- &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
963
- vec![RequestCancelActivity { seq: activity_id }.into()],
964
- ),
965
- gen_assert_and_reply(
966
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(
967
- ResolveActivity {
968
- result: Some(ActivityResolution {
969
- status: Some(activity_resolution::Status::Cancelled(..)),
970
- }),
971
- ..
972
- }
973
- )),
974
- vec![start_timer_cmd(2, Duration::from_secs(1))],
975
- ),
976
- ],
977
- )
978
- .await;
979
- }
980
-
981
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[3]))]
982
- #[tokio::test]
983
- async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static [usize]) {
984
- let wfid = "fake_wf_id";
985
- let t = canned_histories::cancel_not_sent_when_also_complete_repro();
986
- let core = build_fake_worker(wfid, t, hist_batches);
987
- let activity_id = 1;
988
-
989
- poll_and_reply(
990
- &core,
991
- NonSticky,
992
- &[
993
- gen_assert_and_reply(
994
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
995
- vec![ScheduleActivity {
996
- seq: activity_id,
997
- activity_id: "act-1".to_string(),
998
- cancellation_type: ActivityCancellationType::TryCancel as i32,
999
- ..default_act_sched()
1000
- }
1001
- .into()],
1002
- ),
1003
- gen_assert_and_reply(
1004
- &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
1005
- vec![
1006
- RequestCancelActivity { seq: activity_id }.into(),
1007
- start_timer_cmd(2, Duration::from_secs(1)),
1008
- ],
1009
- ),
1010
- gen_assert_and_reply(
1011
- &job_assert!(workflow_activation_job::Variant::ResolveActivity(
1012
- ResolveActivity {
1013
- result: Some(ActivityResolution {
1014
- status: Some(activity_resolution::Status::Cancelled(..)),
1015
- }),
1016
- ..
1017
- }
1018
- )),
1019
- vec![CompleteWorkflowExecution { result: None }.into()],
1020
- ),
1021
- ],
1022
- )
1023
- .await;
1024
- }
1025
-
1026
- #[tokio::test]
1027
- async fn lots_of_workflows() {
1028
- let total_wfs = 500;
1029
- let hists = (0..total_wfs).into_iter().map(|i| {
1030
- let wf_id = format!("fake-wf-{i}");
1031
- let hist = canned_histories::single_timer("1");
1032
- FakeWfResponses {
1033
- wf_id,
1034
- hist,
1035
- response_batches: vec![1.into(), 2.into()],
1036
- }
1037
- });
1038
- let mut mock = build_multihist_mock_sg(hists, false, 0);
1039
- mock.make_wft_stream_interminable();
1040
- let worker = &mock_worker(mock);
1041
- let completed_count = Arc::new(Semaphore::new(0));
1042
- let killer = async {
1043
- let _ = completed_count.acquire_many(total_wfs).await.unwrap();
1044
- worker.initiate_shutdown();
1045
- };
1046
- let poller = fanout_tasks(5, |_| {
1047
- let completed_count = completed_count.clone();
1048
- async move {
1049
- while let Ok(wft) = worker.poll_workflow_activation().await {
1050
- let job = &wft.jobs[0];
1051
- let reply = match job.variant {
1052
- Some(workflow_activation_job::Variant::StartWorkflow(_)) => {
1053
- start_timer_cmd(1, Duration::from_secs(1))
1054
- }
1055
- Some(workflow_activation_job::Variant::RemoveFromCache(_)) => {
1056
- worker
1057
- .complete_workflow_activation(WorkflowActivationCompletion::empty(
1058
- wft.run_id,
1059
- ))
1060
- .await
1061
- .unwrap();
1062
- continue;
1063
- }
1064
- _ => {
1065
- completed_count.add_permits(1);
1066
- CompleteWorkflowExecution { result: None }.into()
1067
- }
1068
- };
1069
- worker
1070
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1071
- wft.run_id, reply,
1072
- ))
1073
- .await
1074
- .unwrap();
1075
- }
1076
- }
1077
- });
1078
- join!(killer, poller);
1079
- worker.shutdown().await;
1080
- }
1081
-
1082
- #[rstest(hist_batches, case::incremental(&[1, 2]), case::replay(&[2]))]
1083
- #[tokio::test]
1084
- async fn wft_timeout_repro(hist_batches: &'static [usize]) {
1085
- let wfid = "fake_wf_id";
1086
- let t = canned_histories::wft_timeout_repro();
1087
- let core = build_fake_worker(wfid, t, hist_batches);
1088
- let activity_id = 1;
1089
-
1090
- poll_and_reply(
1091
- &core,
1092
- NonSticky,
1093
- &[
1094
- gen_assert_and_reply(
1095
- &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
1096
- vec![ScheduleActivity {
1097
- seq: activity_id,
1098
- activity_id: activity_id.to_string(),
1099
- cancellation_type: ActivityCancellationType::TryCancel as i32,
1100
- ..default_act_sched()
1101
- }
1102
- .into()],
1103
- ),
1104
- gen_assert_and_reply(
1105
- &job_assert!(
1106
- workflow_activation_job::Variant::SignalWorkflow(_),
1107
- workflow_activation_job::Variant::SignalWorkflow(_),
1108
- workflow_activation_job::Variant::ResolveActivity(ResolveActivity {
1109
- result: Some(ActivityResolution {
1110
- status: Some(activity_resolution::Status::Completed(..)),
1111
- }),
1112
- ..
1113
- })
1114
- ),
1115
- vec![CompleteWorkflowExecution { result: None }.into()],
1116
- ),
1117
- ],
1118
- )
1119
- .await;
1120
- }
1121
-
1122
- #[tokio::test]
1123
- async fn complete_after_eviction() {
1124
- let wfid = "fake_wf_id";
1125
- let t = canned_histories::single_timer("1");
1126
- let mut mock = mock_workflow_client();
1127
- mock.expect_complete_workflow_task().times(0);
1128
- let mock = single_hist_mock_sg(wfid, t, [2], mock, true);
1129
- let core = mock_worker(mock);
1130
-
1131
- let activation = core.poll_workflow_activation().await.unwrap();
1132
- // We just got start workflow, immediately evict
1133
- core.request_workflow_eviction(&activation.run_id);
1134
- // Since we got whole history, we must finish replay before eviction will appear
1135
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1136
- activation.run_id,
1137
- start_timer_cmd(1, Duration::from_secs(1)),
1138
- ))
1139
- .await
1140
- .unwrap();
1141
- let next_activation = core.poll_workflow_activation().await.unwrap();
1142
- assert_matches!(
1143
- next_activation.jobs.as_slice(),
1144
- [WorkflowActivationJob {
1145
- variant: Some(workflow_activation_job::Variant::FireTimer(_)),
1146
- },]
1147
- );
1148
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1149
- next_activation.run_id,
1150
- vec![CompleteWorkflowExecution { result: None }.into()],
1151
- ))
1152
- .await
1153
- .unwrap();
1154
-
1155
- core.shutdown().await;
1156
- }
1157
-
1158
- #[tokio::test]
1159
- async fn sends_appropriate_sticky_task_queue_responses() {
1160
- // This test verifies that when completions are sent with sticky queues enabled, that they
1161
- // include the information that tells the server to enqueue the next task on a sticky queue.
1162
- let wfid = "fake_wf_id";
1163
- let t = canned_histories::single_timer("1");
1164
- let mut mock = mock_workflow_client();
1165
- mock.expect_complete_workflow_task()
1166
- .withf(|comp| comp.sticky_attributes.is_some())
1167
- .times(1)
1168
- .returning(|_| Ok(Default::default()));
1169
- mock.expect_complete_workflow_task().times(0);
1170
- let mut mock = single_hist_mock_sg(wfid, t, [1], mock, false);
1171
- mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
1172
- let core = mock_worker(mock);
1173
-
1174
- let activation = core.poll_workflow_activation().await.unwrap();
1175
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1176
- activation.run_id,
1177
- start_timer_cmd(1, Duration::from_secs(1)),
1178
- ))
1179
- .await
1180
- .unwrap();
1181
- core.shutdown().await;
1182
- }
1183
-
1184
- #[tokio::test]
1185
- async fn new_server_work_while_eviction_outstanding_doesnt_overwrite_activation() {
1186
- let wfid = "fake_wf_id";
1187
- let t = canned_histories::single_timer("1");
1188
- let mock = single_hist_mock_sg(wfid, t, [1, 2], mock_workflow_client(), false);
1189
- let taskmap = mock.outstanding_task_map.clone().unwrap();
1190
- let core = mock_worker(mock);
1191
-
1192
- // Poll for and complete first workflow task
1193
- let activation = core.poll_workflow_activation().await.unwrap();
1194
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1195
- activation.run_id,
1196
- start_timer_cmd(1, Duration::from_secs(1)),
1197
- ))
1198
- .await
1199
- .unwrap();
1200
- let evict_act = core.poll_workflow_activation().await.unwrap();
1201
- assert_matches!(
1202
- evict_act.jobs.as_slice(),
1203
- [WorkflowActivationJob {
1204
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1205
- }]
1206
- );
1207
- // Ensure mock has delivered both tasks
1208
- assert!(taskmap.all_work_delivered());
1209
- // Now we can complete the evict
1210
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(evict_act.run_id))
1211
- .await
1212
- .unwrap();
1213
- // The task buffered during eviction is applied and we start over
1214
- let start_again = core.poll_workflow_activation().await.unwrap();
1215
- assert_matches!(
1216
- start_again.jobs[0].variant,
1217
- Some(workflow_activation_job::Variant::StartWorkflow(_))
1218
- );
1219
- }
1220
-
1221
- #[tokio::test]
1222
- async fn buffered_work_drained_on_shutdown() {
1223
- let wfid = "fake_wf_id";
1224
- // Build a one-timer history where first task times out
1225
- let mut t = TestHistoryBuilder::default();
1226
- t.add_by_type(EventType::WorkflowExecutionStarted);
1227
- t.add_workflow_task_scheduled_and_started();
1228
- // Need to build the first response before adding the timeout events b/c otherwise the history
1229
- // builder will include them in the first task
1230
- let resp_1 = hist_to_poll_resp(&t, wfid.to_owned(), 1.into()).resp;
1231
- t.add_workflow_task_timed_out();
1232
- t.add_full_wf_task();
1233
- let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
1234
- t.add(history_event::Attributes::TimerFiredEventAttributes(
1235
- TimerFiredEventAttributes {
1236
- started_event_id: timer_started_event_id,
1237
- timer_id: "1".to_string(),
1238
- },
1239
- ));
1240
- t.add_full_wf_task();
1241
- t.add_workflow_execution_completed();
1242
-
1243
- let mut tasks = VecDeque::from(vec![resp_1]);
1244
- // Extend the task list with the now timeout-included version of the task. We add a bunch of
1245
- // them because the poll loop will spin while new tasks are available and it is buffering them
1246
- tasks.extend(
1247
- std::iter::repeat_with(|| hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp).take(50),
1248
- );
1249
- let mut mock = mock_workflow_client();
1250
- mock.expect_complete_workflow_task()
1251
- .returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
1252
- let mut mock = MocksHolder::from_wft_stream(mock, stream::iter(tasks));
1253
- // Cache on to avoid being super repetitive
1254
- mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
1255
- let core = &mock_worker(mock);
1256
-
1257
- // Poll for first WFT
1258
- let act1 = core.poll_workflow_activation().await.unwrap();
1259
- let poll_fut = async move {
1260
- // Now poll again, which will start spinning, and buffer the next WFT with timer fired in it
1261
- // - it won't stop spinning until the first task is complete
1262
- let t = core.poll_workflow_activation().await.unwrap();
1263
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1264
- t.run_id,
1265
- vec![CompleteWorkflowExecution { result: None }.into()],
1266
- ))
1267
- .await
1268
- .unwrap();
1269
- };
1270
- let complete_first = async move {
1271
- // If the first complete is sent too fast, we may not have had a chance to buffer work.
1272
- tokio::time::sleep(Duration::from_millis(50)).await;
1273
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1274
- act1.run_id,
1275
- start_timer_cmd(1, Duration::from_secs(1)),
1276
- ))
1277
- .await
1278
- .unwrap();
1279
- };
1280
- join!(poll_fut, complete_first, async {
1281
- core.shutdown().await;
1282
- });
1283
- }
1284
-
1285
- #[tokio::test]
1286
- async fn fail_wft_then_recover() {
1287
- let t = canned_histories::long_sequential_timers(1);
1288
- let mut mh = MockPollCfg::from_resp_batches(
1289
- "fake_wf_id",
1290
- t,
1291
- // We need to deliver all of history twice because of eviction
1292
- [ResponseType::AllHistory, ResponseType::AllHistory],
1293
- mock_workflow_client(),
1294
- );
1295
- mh.num_expected_fails = 1;
1296
- mh.expect_fail_wft_matcher =
1297
- Box::new(|_, cause, _| matches!(cause, WorkflowTaskFailedCause::NonDeterministicError));
1298
- let mut mock = build_mock_pollers(mh);
1299
- mock.worker_cfg(|wc| {
1300
- wc.max_cached_workflows = 2;
1301
- });
1302
- let core = mock_worker(mock);
1303
-
1304
- let act = core.poll_workflow_activation().await.unwrap();
1305
- // Start an activity instead of a timer, triggering nondeterminism error
1306
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1307
- act.run_id.clone(),
1308
- vec![ScheduleActivity {
1309
- activity_id: "fake_activity".to_string(),
1310
- ..default_act_sched()
1311
- }
1312
- .into()],
1313
- ))
1314
- .await
1315
- .unwrap();
1316
- // We must handle an eviction now
1317
- let evict_act = core.poll_workflow_activation().await.unwrap();
1318
- assert_eq!(evict_act.run_id, act.run_id);
1319
- assert_matches!(
1320
- evict_act.jobs.as_slice(),
1321
- [WorkflowActivationJob {
1322
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1323
- }]
1324
- );
1325
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(evict_act.run_id))
1326
- .await
1327
- .unwrap();
1328
-
1329
- // Workflow starting over, this time issue the right command
1330
- let act = core.poll_workflow_activation().await.unwrap();
1331
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1332
- act.run_id,
1333
- vec![start_timer_cmd(1, Duration::from_secs(1))],
1334
- ))
1335
- .await
1336
- .unwrap();
1337
- let act = core.poll_workflow_activation().await.unwrap();
1338
- assert_matches!(
1339
- act.jobs.as_slice(),
1340
- [WorkflowActivationJob {
1341
- variant: Some(workflow_activation_job::Variant::FireTimer(_)),
1342
- },]
1343
- );
1344
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1345
- act.run_id,
1346
- vec![CompleteWorkflowExecution { result: None }.into()],
1347
- ))
1348
- .await
1349
- .unwrap();
1350
- core.shutdown().await;
1351
- }
1352
-
1353
- #[tokio::test]
1354
- async fn poll_response_triggers_wf_error() {
1355
- let mut t = TestHistoryBuilder::default();
1356
- t.add_by_type(EventType::WorkflowExecutionStarted);
1357
- // Add this nonsense event here to make applying the poll response fail
1358
- t.add_external_signal_completed(100);
1359
- t.add_full_wf_task();
1360
- t.add_workflow_execution_completed();
1361
-
1362
- let mut mh = MockPollCfg::from_resp_batches(
1363
- "fake_wf_id",
1364
- t,
1365
- [ResponseType::AllHistory],
1366
- mock_workflow_client(),
1367
- );
1368
- // Fail wft will be called when auto-failing.
1369
- mh.num_expected_fails = 1;
1370
- mh.expect_fail_wft_matcher = Box::new(move |_, cause, _| {
1371
- matches!(cause, WorkflowTaskFailedCause::NonDeterministicError)
1372
- });
1373
- let mock = build_mock_pollers(mh);
1374
- let core = mock_worker(mock);
1375
- // Poll for first WFT, which is immediately an eviction
1376
- let act = core.poll_workflow_activation().await.unwrap();
1377
- assert_matches!(
1378
- act.jobs.as_slice(),
1379
- [WorkflowActivationJob {
1380
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1381
- }]
1382
- );
1383
- }
1384
-
1385
- // Verifies we can handle multiple wft timeouts in a row if lang is being very slow in responding
1386
- #[tokio::test]
1387
- async fn lang_slower_than_wft_timeouts() {
1388
- let wfid = "fake_wf_id";
1389
- let mut t = TestHistoryBuilder::default();
1390
- t.add_by_type(EventType::WorkflowExecutionStarted);
1391
- t.add_workflow_task_scheduled_and_started();
1392
- t.add_workflow_task_timed_out();
1393
- t.add_full_wf_task();
1394
- t.add_workflow_execution_completed();
1395
-
1396
- let mut mock = mock_workflow_client();
1397
- mock.expect_complete_workflow_task()
1398
- .times(1)
1399
- .returning(|_| Err(tonic::Status::not_found("Workflow task not found.")));
1400
- mock.expect_complete_workflow_task()
1401
- .times(1)
1402
- .returning(|_| Ok(Default::default()));
1403
- let mut mock = single_hist_mock_sg(wfid, t, [1, 1], mock, true);
1404
- let tasksmap = mock.outstanding_task_map.clone().unwrap();
1405
- mock.worker_cfg(|wc| {
1406
- wc.max_cached_workflows = 2;
1407
- });
1408
- let core = mock_worker(mock);
1409
-
1410
- // This completion runs into the workflow task not found error
1411
- let wf_task = core.poll_workflow_activation().await.unwrap();
1412
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
1413
- .await
1414
- .unwrap();
1415
- // It will get an eviction
1416
- let wf_task = core.poll_workflow_activation().await.unwrap();
1417
- assert_matches!(
1418
- wf_task.jobs.as_slice(),
1419
- [WorkflowActivationJob {
1420
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1421
- }]
1422
- );
1423
- // Before we complete, unlock the next task from the mock so that we'll see it get buffered.
1424
- tasksmap.release_run(&wf_task.run_id);
1425
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
1426
- .await
1427
- .unwrap();
1428
- // The buffered WFT should be applied now
1429
- let start_again = core.poll_workflow_activation().await.unwrap();
1430
- assert_matches!(
1431
- start_again.jobs[0].variant,
1432
- Some(workflow_activation_job::Variant::StartWorkflow(_))
1433
- );
1434
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1435
- start_again.run_id,
1436
- vec![CompleteWorkflowExecution { result: None }.into()],
1437
- ))
1438
- .await
1439
- .unwrap();
1440
- core.shutdown().await;
1441
- }
1442
-
1443
- #[tokio::test]
1444
- async fn tries_cancel_of_completed_activity() {
1445
- let mut t = TestHistoryBuilder::default();
1446
- t.add_by_type(EventType::WorkflowExecutionStarted);
1447
- t.add_full_wf_task();
1448
- let scheduled_event_id = t.add_activity_task_scheduled("1");
1449
- t.add_we_signaled("sig", vec![]);
1450
- let started_event_id = t.add_activity_task_started(scheduled_event_id);
1451
- t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
1452
- t.add_workflow_task_scheduled_and_started();
1453
-
1454
- let mock = mock_workflow_client();
1455
- let mut mock = single_hist_mock_sg("fake_wf_id", t, [1, 2], mock, true);
1456
- mock.worker_cfg(|cfg| cfg.max_cached_workflows = 1);
1457
- let core = mock_worker(mock);
1458
-
1459
- let activation = core.poll_workflow_activation().await.unwrap();
1460
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1461
- activation.run_id,
1462
- ScheduleActivity {
1463
- seq: 1,
1464
- activity_id: "1".to_string(),
1465
- ..default_act_sched()
1466
- }
1467
- .into(),
1468
- ))
1469
- .await
1470
- .unwrap();
1471
- let activation = core.poll_workflow_activation().await.unwrap();
1472
- assert_matches!(
1473
- activation.jobs.as_slice(),
1474
- [
1475
- WorkflowActivationJob {
1476
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1477
- },
1478
- WorkflowActivationJob {
1479
- variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
1480
- }
1481
- ]
1482
- );
1483
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1484
- activation.run_id,
1485
- vec![
1486
- RequestCancelActivity { seq: 1 }.into(),
1487
- CompleteWorkflowExecution { result: None }.into(),
1488
- ],
1489
- ))
1490
- .await
1491
- .unwrap();
1492
-
1493
- core.shutdown().await;
1494
- }
1495
-
1496
- #[tokio::test]
1497
- async fn failing_wft_doesnt_eat_permit_forever() {
1498
- let mut t = TestHistoryBuilder::default();
1499
- t.add_by_type(EventType::WorkflowExecutionStarted);
1500
- t.add_workflow_task_scheduled_and_started();
1501
-
1502
- let mock = mock_workflow_client();
1503
- let mut mock = MockPollCfg::from_resp_batches("fake_wf_id", t, [1, 1, 1], mock);
1504
- mock.num_expected_fails = 1;
1505
- let mut mock = build_mock_pollers(mock);
1506
- mock.worker_cfg(|cfg| {
1507
- cfg.max_cached_workflows = 2;
1508
- cfg.max_outstanding_workflow_tasks = 2;
1509
- });
1510
- let outstanding_mock_tasks = mock.outstanding_task_map.clone();
1511
- let worker = mock_worker(mock);
1512
-
1513
- let mut run_id = "".to_string();
1514
- // Fail twice, verifying a permit is not eaten. We cannot fail the same run more than twice in a
1515
- // row because we purposefully time out rather than spamming.
1516
- for _ in 1..=2 {
1517
- let activation = worker.poll_workflow_activation().await.unwrap();
1518
- // Issue a nonsense completion that will trigger a WFT failure
1519
- worker
1520
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1521
- activation.run_id,
1522
- RequestCancelActivity { seq: 1 }.into(),
1523
- ))
1524
- .await
1525
- .unwrap();
1526
- let activation = worker.poll_workflow_activation().await.unwrap();
1527
- assert_matches!(
1528
- activation.jobs.as_slice(),
1529
- [WorkflowActivationJob {
1530
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1531
- },]
1532
- );
1533
- run_id = activation.run_id.clone();
1534
- worker
1535
- .complete_workflow_activation(WorkflowActivationCompletion::empty(activation.run_id))
1536
- .await
1537
- .unwrap();
1538
- }
1539
- assert_eq!(worker.outstanding_workflow_tasks().await, 0);
1540
- // 1 permit is in use because the next task is buffered and has re-used the permit
1541
- assert_eq!(worker.available_wft_permits().await, 1);
1542
- // We should be "out of work" because the mock service thinks we didn't complete the last task,
1543
- // which we didn't, because we don't spam failures. The real server would eventually time out
1544
- // the task. Mock doesn't understand that, so the WFT permit is released because eventually a
1545
- // new one will be generated. We manually clear the mock's outstanding task list so the next
1546
- // poll will work.
1547
- outstanding_mock_tasks.unwrap().release_run(&run_id);
1548
- let activation = worker.poll_workflow_activation().await.unwrap();
1549
- // There should be no change in permits, since this just unbuffered the buffered task
1550
- assert_eq!(worker.available_wft_permits().await, 1);
1551
- worker
1552
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1553
- activation.run_id,
1554
- CompleteWorkflowExecution { result: None }.into(),
1555
- ))
1556
- .await
1557
- .unwrap();
1558
- worker.shutdown().await;
1559
- assert_eq!(worker.available_wft_permits().await, 2);
1560
- }
1561
-
1562
- #[tokio::test]
1563
- async fn cache_miss_will_fetch_history() {
1564
- let mut t = TestHistoryBuilder::default();
1565
- t.add_by_type(EventType::WorkflowExecutionStarted);
1566
- t.add_full_wf_task();
1567
- t.add_we_signaled("sig", vec![]);
1568
- t.add_full_wf_task();
1569
- t.add_workflow_execution_completed();
1570
- let get_exec_resp: GetWorkflowExecutionHistoryResponse = t.get_history_info(2).unwrap().into();
1571
-
1572
- let mut mh = MockPollCfg::from_resp_batches(
1573
- "fake_wf_id",
1574
- t,
1575
- [ResponseType::ToTaskNum(1), ResponseType::OneTask(2)],
1576
- mock_workflow_client(),
1577
- );
1578
- mh.mock_client
1579
- .expect_get_workflow_execution_history()
1580
- .times(1)
1581
- .returning(move |_, _, _| Ok(get_exec_resp.clone()));
1582
- let mut mock = build_mock_pollers(mh);
1583
- mock.worker_cfg(|cfg| {
1584
- cfg.max_cached_workflows = 1;
1585
- // Also verifies tying the WFT permit to the fetch request doesn't get us stuck
1586
- cfg.max_outstanding_workflow_tasks = 1;
1587
- });
1588
- let worker = mock_worker(mock);
1589
-
1590
- let activation = worker.poll_workflow_activation().await.unwrap();
1591
- assert_eq!(activation.history_length, 3);
1592
- assert_matches!(
1593
- activation.jobs.as_slice(),
1594
- [WorkflowActivationJob {
1595
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
1596
- }]
1597
- );
1598
- // Force an eviction (before complete matters, so that we will be sure the eviction is queued
1599
- // up before the next fake WFT is unlocked)
1600
- worker.request_wf_eviction(
1601
- &activation.run_id,
1602
- "whatever",
1603
- EvictionReason::LangRequested,
1604
- );
1605
- worker
1606
- .complete_workflow_activation(WorkflowActivationCompletion::empty(&activation.run_id))
1607
- .await
1608
- .unwrap();
1609
- // Handle the eviction, and the restart
1610
- for i in 1..=2 {
1611
- let activation = worker.poll_workflow_activation().await.unwrap();
1612
- assert_eq!(activation.history_length, 3);
1613
- if i == 1 {
1614
- assert_matches!(
1615
- activation.jobs.as_slice(),
1616
- [WorkflowActivationJob {
1617
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1618
- }]
1619
- );
1620
- } else {
1621
- assert_matches!(
1622
- activation.jobs.as_slice(),
1623
- [WorkflowActivationJob {
1624
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
1625
- }]
1626
- );
1627
- }
1628
- worker
1629
- .complete_workflow_activation(WorkflowActivationCompletion::empty(activation.run_id))
1630
- .await
1631
- .unwrap();
1632
- }
1633
- let activation = worker.poll_workflow_activation().await.unwrap();
1634
- assert_eq!(activation.history_length, 7);
1635
- assert_matches!(
1636
- activation.jobs.as_slice(),
1637
- [WorkflowActivationJob {
1638
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1639
- }]
1640
- );
1641
- worker
1642
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1643
- activation.run_id,
1644
- CompleteWorkflowExecution { result: None }.into(),
1645
- ))
1646
- .await
1647
- .unwrap();
1648
- assert_eq!(worker.outstanding_workflow_tasks().await, 0);
1649
- worker.shutdown().await;
1650
- }
1651
-
1652
- /// This test verifies that WFTs which come as replies to completing a WFT are properly delivered
1653
- /// via activation polling.
1654
- #[tokio::test]
1655
- async fn tasks_from_completion_are_delivered() {
1656
- let wfid = "fake_wf_id";
1657
- let mut t = TestHistoryBuilder::default();
1658
- t.add_by_type(EventType::WorkflowExecutionStarted);
1659
- t.add_full_wf_task();
1660
- t.add_we_signaled("sig", vec![]);
1661
- t.add_full_wf_task();
1662
- t.add_workflow_execution_completed();
1663
-
1664
- let mut mock = mock_workflow_client();
1665
- let complete_resp = RespondWorkflowTaskCompletedResponse {
1666
- workflow_task: Some(hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp),
1667
- activity_tasks: vec![],
1668
- reset_history_event_id: 0,
1669
- };
1670
- mock.expect_complete_workflow_task()
1671
- .times(1)
1672
- .returning(move |_| Ok(complete_resp.clone()));
1673
- mock.expect_complete_workflow_task()
1674
- .times(1)
1675
- .returning(|_| Ok(Default::default()));
1676
- let mut mock = single_hist_mock_sg(wfid, t, [1], mock, true);
1677
- mock.worker_cfg(|wc| wc.max_cached_workflows = 2);
1678
- let core = mock_worker(mock);
1679
-
1680
- let wf_task = core.poll_workflow_activation().await.unwrap();
1681
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
1682
- .await
1683
- .unwrap();
1684
- let wf_task = core.poll_workflow_activation().await.unwrap();
1685
- assert_matches!(
1686
- wf_task.jobs.as_slice(),
1687
- [WorkflowActivationJob {
1688
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1689
- },]
1690
- );
1691
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1692
- wf_task.run_id,
1693
- vec![CompleteWorkflowExecution { result: None }.into()],
1694
- ))
1695
- .await
1696
- .unwrap();
1697
- core.shutdown().await;
1698
- }
1699
-
1700
- #[tokio::test]
1701
- async fn pagination_works_with_tasks_from_completion() {
1702
- let wfid = "fake_wf_id";
1703
- let mut t = TestHistoryBuilder::default();
1704
- t.add_by_type(EventType::WorkflowExecutionStarted);
1705
- t.add_full_wf_task();
1706
- t.add_we_signaled("sig", vec![]);
1707
- t.add_full_wf_task();
1708
- t.add_workflow_execution_completed();
1709
- let get_exec_resp: GetWorkflowExecutionHistoryResponse = t.get_history_info(2).unwrap().into();
1710
-
1711
- let mut mock = mock_workflow_client();
1712
- let mut needs_pag_resp = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2)).resp;
1713
- needs_pag_resp.next_page_token = vec![1];
1714
- let complete_resp = RespondWorkflowTaskCompletedResponse {
1715
- workflow_task: Some(needs_pag_resp),
1716
- ..Default::default()
1717
- };
1718
- mock.expect_complete_workflow_task()
1719
- .times(1)
1720
- .returning(move |_| Ok(complete_resp.clone()));
1721
- mock.expect_complete_workflow_task()
1722
- .times(1)
1723
- .returning(|_| Ok(Default::default()));
1724
- mock.expect_get_workflow_execution_history()
1725
- .returning(move |_, _, _| Ok(get_exec_resp.clone()))
1726
- .times(1);
1727
- let mut mock = single_hist_mock_sg(wfid, t, [1], mock, true);
1728
- mock.worker_cfg(|wc| wc.max_cached_workflows = 2);
1729
- let core = mock_worker(mock);
1730
-
1731
- let wf_task = core.poll_workflow_activation().await.unwrap();
1732
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
1733
- .await
1734
- .unwrap();
1735
- let wf_task = core.poll_workflow_activation().await.unwrap();
1736
- assert_matches!(
1737
- wf_task.jobs.as_slice(),
1738
- [WorkflowActivationJob {
1739
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1740
- },]
1741
- );
1742
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1743
- wf_task.run_id,
1744
- vec![CompleteWorkflowExecution { result: None }.into()],
1745
- ))
1746
- .await
1747
- .unwrap();
1748
- core.shutdown().await;
1749
- }
1750
-
1751
- #[tokio::test]
1752
- async fn poll_faster_than_complete_wont_overflow_cache() {
1753
- // Make workflow tasks for 5 different runs
1754
- let tasks: Vec<_> = (1..=5)
1755
- .map(|i| FakeWfResponses {
1756
- wf_id: format!("wf-{i}"),
1757
- hist: canned_histories::single_timer("1"),
1758
- response_batches: vec![ResponseType::ToTaskNum(1)],
1759
- })
1760
- .collect();
1761
- let mut mock_client = mock_workflow_client();
1762
- mock_client
1763
- .expect_complete_workflow_task()
1764
- .times(3)
1765
- .returning(|_| Ok(Default::default()));
1766
- let mut mock_cfg = MockPollCfg::new(tasks, true, 0);
1767
- mock_cfg.mock_client = mock_client;
1768
- let mut mock = build_mock_pollers(mock_cfg);
1769
- mock.worker_cfg(|wc| {
1770
- wc.max_cached_workflows = 3;
1771
- wc.max_outstanding_workflow_tasks = 3;
1772
- });
1773
- let core = mock_worker(mock);
1774
- // Poll 4 times, completing once, such that max tasks are never exceeded
1775
- let p1 = core.poll_workflow_activation().await.unwrap();
1776
- let p2 = core.poll_workflow_activation().await.unwrap();
1777
- let p3 = core.poll_workflow_activation().await.unwrap();
1778
- for (i, p_res) in [&p1, &p2, &p3].into_iter().enumerate() {
1779
- assert_matches!(
1780
- &p_res.jobs[0].variant,
1781
- Some(workflow_activation_job::Variant::StartWorkflow(sw))
1782
- if sw.workflow_id == format!("wf-{}", i + 1)
1783
- );
1784
- }
1785
- // Complete first task to free a wft slot. Cache size is at 3
1786
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1787
- p1.run_id,
1788
- start_timer_cmd(1, Duration::from_secs(1)),
1789
- ))
1790
- .await
1791
- .unwrap();
1792
- // Now we're at cache limit. We will poll for a task, discover it is for a new run, issue
1793
- // an eviction, and buffer the new run task. However, the run we're trying to evict has pending
1794
- // activations! Thus, we must complete them first before this poll will unblock, and then it
1795
- // will unblock with the eviciton.
1796
- let p4 = core.poll_workflow_activation();
1797
- // Make sure the task gets buffered before we start the complete, so the LRU list is in the
1798
- // expected order and what we expect to evict will be evicted.
1799
- advance_fut!(p4);
1800
- let p4 = async {
1801
- let p4 = p4.await.unwrap();
1802
- assert_matches!(
1803
- &p4.jobs.as_slice(),
1804
- [WorkflowActivationJob {
1805
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1806
- }]
1807
- );
1808
- p4
1809
- };
1810
- let p2_pending_completer = async {
1811
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1812
- p2.run_id,
1813
- start_timer_cmd(1, Duration::from_secs(1)),
1814
- ))
1815
- .await
1816
- .unwrap();
1817
- };
1818
- let (p4, _) = join!(p4, p2_pending_completer);
1819
- assert_eq!(core.cached_workflows().await, 3);
1820
-
1821
- // This poll should also block until the eviction is actually completed
1822
- let blocking_poll = async {
1823
- let res = core.poll_workflow_activation().await.unwrap();
1824
- assert_matches!(
1825
- &res.jobs[0].variant,
1826
- Some(workflow_activation_job::Variant::StartWorkflow(sw))
1827
- if sw.workflow_id == format!("wf-{}", 4)
1828
- );
1829
- res
1830
- };
1831
- let complete_evict = async {
1832
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(p4.run_id))
1833
- .await
1834
- .unwrap();
1835
- };
1836
-
1837
- let (_p5, _) = join!(blocking_poll, complete_evict);
1838
- assert_eq!(core.cached_workflows().await, 3);
1839
- // The next poll will get an buffer a task for a new run, and generate an eviction for p3 but
1840
- // that eviction cannot be obtained until we complete the existing outstanding task.
1841
- let p6 = async {
1842
- let p6 = core.poll_workflow_activation().await.unwrap();
1843
- assert_matches!(
1844
- p6.jobs.as_slice(),
1845
- [WorkflowActivationJob {
1846
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1847
- }]
1848
- );
1849
- p6
1850
- };
1851
- let completer = async {
1852
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1853
- p3.run_id,
1854
- start_timer_cmd(1, Duration::from_secs(1)),
1855
- ))
1856
- .await
1857
- .unwrap();
1858
- };
1859
- let (p6, _) = join!(p6, completer);
1860
- let complete_evict = async {
1861
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(p6.run_id))
1862
- .await
1863
- .unwrap();
1864
- };
1865
- let blocking_poll = async {
1866
- // This poll will also block until the last eviction goes through, and when it does it'll
1867
- // produce the final start workflow task
1868
- let res = core.poll_workflow_activation().await.unwrap();
1869
- assert_matches!(
1870
- &res.jobs[0].variant,
1871
- Some(workflow_activation_job::Variant::StartWorkflow(sw))
1872
- if sw.workflow_id == "wf-5"
1873
- );
1874
- };
1875
-
1876
- join!(blocking_poll, complete_evict);
1877
- // p5 outstanding and final poll outstanding -- hence one permit available
1878
- assert_eq!(core.available_wft_permits().await, 1);
1879
- assert_eq!(core.cached_workflows().await, 3);
1880
- }
1881
-
1882
- #[tokio::test]
1883
- async fn eviction_waits_until_replay_finished() {
1884
- let wfid = "fake_wf_id";
1885
- let t = canned_histories::long_sequential_timers(3);
1886
- let mock = mock_workflow_client();
1887
- let mock = single_hist_mock_sg(wfid, t, [3], mock, true);
1888
- let core = mock_worker(mock);
1889
-
1890
- let activation = core.poll_workflow_activation().await.unwrap();
1891
- assert_eq!(activation.history_length, 3);
1892
- // Immediately request eviction after getting start workflow
1893
- core.request_workflow_eviction(&activation.run_id);
1894
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1895
- activation.run_id,
1896
- start_timer_cmd(1, Duration::from_secs(1)),
1897
- ))
1898
- .await
1899
- .unwrap();
1900
- let t1_fired = core.poll_workflow_activation().await.unwrap();
1901
- assert_eq!(t1_fired.history_length, 8);
1902
- assert_matches!(
1903
- t1_fired.jobs.as_slice(),
1904
- [WorkflowActivationJob {
1905
- variant: Some(workflow_activation_job::Variant::FireTimer(_)),
1906
- }]
1907
- );
1908
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1909
- t1_fired.run_id,
1910
- start_timer_cmd(2, Duration::from_secs(1)),
1911
- ))
1912
- .await
1913
- .unwrap();
1914
- let t2_fired = core.poll_workflow_activation().await.unwrap();
1915
- assert_eq!(t2_fired.history_length, 13);
1916
- assert_matches!(
1917
- t2_fired.jobs.as_slice(),
1918
- [WorkflowActivationJob {
1919
- variant: Some(workflow_activation_job::Variant::FireTimer(_)),
1920
- }]
1921
- );
1922
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1923
- t2_fired.run_id,
1924
- vec![CompleteWorkflowExecution { result: None }.into()],
1925
- ))
1926
- .await
1927
- .unwrap();
1928
-
1929
- core.shutdown().await;
1930
- }
1931
-
1932
- #[tokio::test]
1933
- async fn autocompletes_wft_no_work() {
1934
- let wfid = "fake_wf_id";
1935
- let activity_id = "1";
1936
-
1937
- let mut t = TestHistoryBuilder::default();
1938
- t.add_by_type(EventType::WorkflowExecutionStarted);
1939
- t.add_full_wf_task();
1940
- let scheduled_event_id = t.add_activity_task_scheduled(activity_id);
1941
- t.add_full_wf_task();
1942
- t.add_we_signaled("sig1", vec![]);
1943
- t.add_full_wf_task();
1944
- let started_event_id = t.add_activity_task_started(scheduled_event_id);
1945
- t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
1946
- t.add_full_wf_task();
1947
- let mock = mock_workflow_client();
1948
- let mut mock = single_hist_mock_sg(wfid, t, [1, 2, 3, 4], mock, true);
1949
- mock.worker_cfg(|w| w.max_cached_workflows = 1);
1950
- let core = mock_worker(mock);
1951
-
1952
- let act = core.poll_workflow_activation().await.unwrap();
1953
- assert_matches!(
1954
- act.jobs.as_slice(),
1955
- [WorkflowActivationJob {
1956
- variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
1957
- }]
1958
- );
1959
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1960
- act.run_id,
1961
- ScheduleActivity {
1962
- seq: 1,
1963
- activity_id: activity_id.to_string(),
1964
- cancellation_type: ActivityCancellationType::Abandon as i32,
1965
- ..default_act_sched()
1966
- }
1967
- .into(),
1968
- ))
1969
- .await
1970
- .unwrap();
1971
- let act = core.poll_workflow_activation().await.unwrap();
1972
- assert_matches!(
1973
- act.jobs.as_slice(),
1974
- [WorkflowActivationJob {
1975
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1976
- }]
1977
- );
1978
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1979
- act.run_id,
1980
- RequestCancelActivity { seq: 1 }.into(),
1981
- ))
1982
- .await
1983
- .unwrap();
1984
- let act = core.poll_workflow_activation().await.unwrap();
1985
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
1986
- .await
1987
- .unwrap();
1988
- // The last task will autocomplete, and thus this will return shutdown since there is no more
1989
- // work
1990
- assert_matches!(
1991
- core.poll_workflow_activation().await.unwrap_err(),
1992
- PollWfError::ShutDown
1993
- );
1994
-
1995
- core.shutdown().await;
1996
- }
1997
-
1998
- #[tokio::test]
1999
- async fn no_race_acquiring_permits() {
2000
- let wfid = "fake_wf_id";
2001
- let mut mock_client = mock_manual_workflow_client();
2002
- // We need to allow two polls to happen by triggering two processing events in the workflow
2003
- // stream, but then delivering the actual tasks after that
2004
- let task_barr: &'static Barrier = Box::leak(Box::new(Barrier::new(2)));
2005
- mock_client
2006
- .expect_poll_workflow_task()
2007
- .returning(move |_, _| {
2008
- let t = canned_histories::single_timer("1");
2009
- let poll_resp = hist_to_poll_resp(&t, wfid.to_owned(), 2.into()).resp;
2010
- async move {
2011
- task_barr.wait().await;
2012
- Ok(poll_resp.clone())
2013
- }
2014
- .boxed()
2015
- });
2016
- mock_client
2017
- .expect_complete_workflow_task()
2018
- .returning(|_| async move { Ok(Default::default()) }.boxed());
2019
-
2020
- let worker = Worker::new_test(
2021
- test_worker_cfg()
2022
- .max_outstanding_workflow_tasks(1_usize)
2023
- .max_cached_workflows(10_usize)
2024
- .build()
2025
- .unwrap(),
2026
- mock_client,
2027
- );
2028
-
2029
- // Two polls in a row, both of which will get stuck on the barrier and are only allowed to
2030
- // proceed after a call which will cause the workflow stream to process an event. Without the
2031
- // fix, this would've meant the stream though it was OK to poll twice, but once the tasks
2032
- // are received, it would find there was only one permit.
2033
- let poll_1_f = async {
2034
- let r = worker.poll_workflow_activation().await.unwrap();
2035
- worker
2036
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
2037
- r.run_id,
2038
- start_timer_cmd(1, Duration::from_secs(1)),
2039
- ))
2040
- .await
2041
- .unwrap();
2042
- };
2043
- let poll_2_f = async {
2044
- let r = worker.poll_workflow_activation().await.unwrap();
2045
- worker
2046
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
2047
- r.run_id,
2048
- start_timer_cmd(1, Duration::from_secs(1)),
2049
- ))
2050
- .await
2051
- .unwrap();
2052
- };
2053
- let other_f = async {
2054
- worker.cached_workflows().await;
2055
- task_barr.wait().await;
2056
- worker.cached_workflows().await;
2057
- task_barr.wait().await;
2058
- };
2059
- join!(poll_1_f, poll_2_f, other_f);
2060
- }
2061
-
2062
- #[tokio::test]
2063
- async fn continue_as_new_preserves_some_values() {
2064
- let wfid = "fake_wf_id";
2065
- let memo = HashMap::<String, Payload>::from([("enchi".to_string(), b"cat".into())]).into();
2066
- let search = HashMap::<String, Payload>::from([("noisy".to_string(), b"kitty".into())]).into();
2067
- let retry_policy = RetryPolicy {
2068
- backoff_coefficient: 13.37,
2069
- ..Default::default()
2070
- };
2071
- let mut wes_attrs = default_wes_attribs();
2072
- wes_attrs.memo = Some(memo);
2073
- wes_attrs.search_attributes = Some(search);
2074
- wes_attrs.retry_policy = Some(retry_policy);
2075
- let mut mock_client = mock_workflow_client();
2076
- let hist = {
2077
- let mut t = TestHistoryBuilder::default();
2078
- t.add(wes_attrs.clone());
2079
- t.add_full_wf_task();
2080
- t
2081
- };
2082
- mock_client
2083
- .expect_poll_workflow_task()
2084
- .returning(move |_, _| {
2085
- Ok(hist_to_poll_resp(&hist, wfid.to_owned(), ResponseType::AllHistory).resp)
2086
- });
2087
- mock_client
2088
- .expect_complete_workflow_task()
2089
- .returning(move |mut c| {
2090
- let can_cmd = c.commands.pop().unwrap().attributes.unwrap();
2091
- if let Attributes::ContinueAsNewWorkflowExecutionCommandAttributes(a) = can_cmd {
2092
- assert_eq!(a.workflow_type.unwrap().name, "meow");
2093
- assert_eq!(a.memo, wes_attrs.memo);
2094
- assert_eq!(a.search_attributes, wes_attrs.search_attributes);
2095
- assert_eq!(a.retry_policy, wes_attrs.retry_policy);
2096
- } else {
2097
- panic!("Wrong attributes type");
2098
- }
2099
- Ok(Default::default())
2100
- });
2101
-
2102
- let worker = Worker::new_test(test_worker_cfg().build().unwrap(), mock_client);
2103
- let r = worker.poll_workflow_activation().await.unwrap();
2104
- worker
2105
- .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
2106
- r.run_id,
2107
- ContinueAsNewWorkflowExecution {
2108
- workflow_type: "meow".to_string(),
2109
- ..Default::default()
2110
- }
2111
- .into(),
2112
- ))
2113
- .await
2114
- .unwrap();
2115
- }
2116
-
2117
- #[rstest]
2118
- #[tokio::test]
2119
- async fn ignorable_events_are_ok(#[values(true, false)] attribs_unset: bool) {
2120
- let mut t = TestHistoryBuilder::default();
2121
- t.add_by_type(EventType::WorkflowExecutionStarted);
2122
- let id = t.add(WorkflowPropertiesModifiedExternallyEventAttributes::default());
2123
- t.modify_event(id, |e| {
2124
- e.worker_may_ignore = true;
2125
- // Ignorable events are ignored if we can't interpret the proto of either the event attribs
2126
- // or proto - otherwise (this is the _may_ part of may ignore), we'll still try to process
2127
- // it. That processing may ultimately still choose to do nothing, if we want to _explicitly_
2128
- // ignore it.
2129
- if attribs_unset {
2130
- e.attributes = None;
2131
- } else {
2132
- e.event_type = EventType::Unspecified as i32;
2133
- }
2134
- });
2135
- t.add_workflow_task_scheduled_and_started();
2136
-
2137
- let mock = mock_workflow_client();
2138
- let mock = single_hist_mock_sg("wheee", t, [ResponseType::AllHistory], mock, true);
2139
- let core = mock_worker(mock);
2140
-
2141
- let act = core.poll_workflow_activation().await.unwrap();
2142
- assert_matches!(
2143
- act.jobs[0].variant,
2144
- Some(workflow_activation_job::Variant::StartWorkflow(_))
2145
- );
2146
- }
2147
-
2148
- #[tokio::test]
2149
- async fn fetching_to_continue_replay_works() {
2150
- let mut mock_client = mock_workflow_client();
2151
- let mut t = TestHistoryBuilder::default();
2152
- t.add_by_type(EventType::WorkflowExecutionStarted);
2153
- t.add_full_wf_task();
2154
- t.add_full_wf_task(); // ends 7
2155
- let mut need_fetch_resp =
2156
- hist_to_poll_resp(&t, "wfid".to_owned(), ResponseType::AllHistory).resp;
2157
- need_fetch_resp.next_page_token = vec![1];
2158
-
2159
- t.add_full_wf_task();
2160
- t.add_we_signaled("hi", vec![]); // Need to make there be two complete WFTs
2161
- t.add_full_wf_task(); // end 14
2162
- let mut fetch_resp: GetWorkflowExecutionHistoryResponse =
2163
- t.get_full_history_info().unwrap().into();
2164
- // Should only contain events after 7
2165
- if let Some(ref mut h) = fetch_resp.history {
2166
- h.events.retain(|e| e.event_id >= 8);
2167
- }
2168
- // And indicate that even *more* needs to be fetched after this, so we see a request for the
2169
- // next page happen.
2170
- fetch_resp.next_page_token = vec![2];
2171
-
2172
- let timer_started_event_id = t.add_by_type(EventType::TimerStarted);
2173
- t.add_timer_fired(timer_started_event_id, "1".to_string());
2174
- t.add_full_wf_task();
2175
- let mut final_fetch_resp: GetWorkflowExecutionHistoryResponse =
2176
- t.get_full_history_info().unwrap().into();
2177
- // Should have only the final event
2178
- if let Some(ref mut h) = final_fetch_resp.history {
2179
- h.events.retain(|e| e.event_id >= 15);
2180
- }
2181
-
2182
- let tasks = vec![
2183
- ResponseType::ToTaskNum(1),
2184
- ResponseType::Raw(need_fetch_resp),
2185
- ];
2186
- mock_client
2187
- .expect_get_workflow_execution_history()
2188
- .returning(move |_, _, _| Ok(fetch_resp.clone()))
2189
- .times(1);
2190
- mock_client
2191
- .expect_get_workflow_execution_history()
2192
- .returning(move |_, _, _| Ok(final_fetch_resp.clone()))
2193
- .times(1);
2194
- let mut mock = single_hist_mock_sg("wfid", t, tasks, mock_client, true);
2195
- mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
2196
- let core = mock_worker(mock);
2197
- let act = core.poll_workflow_activation().await.unwrap();
2198
- assert_matches!(
2199
- act.jobs[0].variant,
2200
- Some(workflow_activation_job::Variant::StartWorkflow(_))
2201
- );
2202
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
2203
- .await
2204
- .unwrap();
2205
- let act = core.poll_workflow_activation().await.unwrap();
2206
- assert_matches!(
2207
- act.jobs.as_slice(),
2208
- [WorkflowActivationJob {
2209
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
2210
- }]
2211
- );
2212
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
2213
- act.run_id,
2214
- start_timer_cmd(1, Duration::from_secs(1)),
2215
- ))
2216
- .await
2217
- .unwrap();
2218
- let act = core.poll_workflow_activation().await.unwrap();
2219
- assert_matches!(
2220
- act.jobs.as_slice(),
2221
- [WorkflowActivationJob {
2222
- variant: Some(workflow_activation_job::Variant::FireTimer(_)),
2223
- }]
2224
- );
2225
- }
2226
-
2227
- #[tokio::test]
2228
- async fn fetching_error_evicts_wf() {
2229
- let mut mock_client = mock_workflow_client();
2230
- let mut t = TestHistoryBuilder::default();
2231
- t.add_by_type(EventType::WorkflowExecutionStarted);
2232
- t.add_workflow_task_scheduled_and_started();
2233
- t.add_workflow_task_completed();
2234
- let mut need_fetch_resp =
2235
- hist_to_poll_resp(&t, "wfid".to_owned(), ResponseType::AllHistory).resp;
2236
- need_fetch_resp.next_page_token = vec![1];
2237
- let tasks = vec![
2238
- ResponseType::ToTaskNum(1),
2239
- ResponseType::Raw(need_fetch_resp),
2240
- ];
2241
- mock_client
2242
- .expect_get_workflow_execution_history()
2243
- .returning(move |_, _, _| Err(tonic::Status::not_found("Ahh broken")))
2244
- .times(1);
2245
- let mut mock = single_hist_mock_sg("wfid", t, tasks, mock_client, true);
2246
- mock.worker_cfg(|wc| wc.max_cached_workflows = 10);
2247
- let core = mock_worker(mock);
2248
- let act = core.poll_workflow_activation().await.unwrap();
2249
- assert_matches!(
2250
- act.jobs[0].variant,
2251
- Some(workflow_activation_job::Variant::StartWorkflow(_))
2252
- );
2253
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
2254
- .await
2255
- .unwrap();
2256
- let evict_act = core.poll_workflow_activation().await.unwrap();
2257
- assert_matches!(
2258
- evict_act.jobs.as_slice(),
2259
- [WorkflowActivationJob {
2260
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(r)),
2261
- }] => r.message.contains("Fetching history failed")
2262
- );
2263
- }
2264
-
2265
- /// This test verifies that if we fail to fetch a page during a completion, that we don't get stuck
2266
- /// in the complete waiting for the completion to finish.
2267
- #[tokio::test]
2268
- async fn ensure_fetching_fail_during_complete_sends_task_failure() {
2269
- let wfid = "fake_wf_id";
2270
- let mut t = TestHistoryBuilder::default();
2271
- t.add_by_type(EventType::WorkflowExecutionStarted);
2272
- t.add_full_wf_task(); // started 3
2273
- t.add_we_signaled("sig1", vec![]);
2274
- t.add_full_wf_task(); // started 7
2275
- t.add_we_signaled("sig2", vec![]);
2276
- t.add_full_wf_task(); // started 11
2277
- t.add_workflow_execution_completed();
2278
-
2279
- let mut first_poll = hist_to_poll_resp(&t, wfid, ResponseType::ToTaskNum(1)).resp;
2280
- first_poll.next_page_token = vec![1];
2281
- first_poll.previous_started_event_id = 3;
2282
-
2283
- let mut next_page: GetWorkflowExecutionHistoryResponse = t.get_history_info(2).unwrap().into();
2284
- next_page.next_page_token = vec![2];
2285
-
2286
- let mut mock = mock_workflow_client();
2287
- mock.expect_get_workflow_execution_history()
2288
- .returning(move |_, _, _| {
2289
- error!("Called fetch!");
2290
- Ok(next_page.clone())
2291
- })
2292
- .times(1);
2293
- let mut really_empty_fetch_resp: GetWorkflowExecutionHistoryResponse =
2294
- t.get_history_info(1).unwrap().into();
2295
- really_empty_fetch_resp.history = Some(Default::default());
2296
- mock.expect_get_workflow_execution_history()
2297
- .returning(move |_, _, _| {
2298
- error!("Called fetch second time!");
2299
- Ok(really_empty_fetch_resp.clone())
2300
- })
2301
- .times(1);
2302
- mock.expect_fail_workflow_task()
2303
- .returning(|_, _, _| Ok(Default::default()))
2304
- .times(1);
2305
-
2306
- let mut mock = single_hist_mock_sg(wfid, t, [ResponseType::Raw(first_poll)], mock, true);
2307
- mock.make_wft_stream_interminable();
2308
- mock.worker_cfg(|wc| wc.max_cached_workflows = 2);
2309
- let core = mock_worker(mock);
2310
-
2311
- let wf_task = core.poll_workflow_activation().await.unwrap();
2312
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
2313
- .await
2314
- .unwrap();
2315
-
2316
- let wf_task = core.poll_workflow_activation().await.unwrap();
2317
- assert_matches!(
2318
- wf_task.jobs.as_slice(),
2319
- [WorkflowActivationJob {
2320
- variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
2321
- },]
2322
- );
2323
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(wf_task.run_id))
2324
- .await
2325
- .unwrap();
2326
-
2327
- // Expect to see eviction b/c of history fetching error here.
2328
- let wf_task = core.poll_workflow_activation().await.unwrap();
2329
- assert_matches!(
2330
- wf_task.jobs.as_slice(),
2331
- [WorkflowActivationJob {
2332
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
2333
- },]
2334
- );
2335
-
2336
- core.shutdown().await;
2337
- }
2338
-
2339
- #[tokio::test]
2340
- async fn lang_internal_flags() {
2341
- let mut t = TestHistoryBuilder::default();
2342
- t.add_by_type(EventType::WorkflowExecutionStarted);
2343
- t.add_full_wf_task();
2344
- t.set_flags_first_wft(&[], &[1]);
2345
- t.add_we_signaled("sig1", vec![]);
2346
- t.add_full_wf_task();
2347
- t.set_flags_last_wft(&[], &[2]);
2348
- t.add_we_signaled("sig2", vec![]);
2349
- t.add_full_wf_task();
2350
- t.add_workflow_execution_completed();
2351
-
2352
- let mut mh = MockPollCfg::from_resp_batches(
2353
- "fake_wf_id",
2354
- t,
2355
- [ResponseType::ToTaskNum(2), ResponseType::AllHistory],
2356
- mock_workflow_client(),
2357
- );
2358
- mh.completion_asserts = Some(Box::new(|c| {
2359
- assert_matches!(c.sdk_metadata.lang_used_flags.as_slice(), &[2]);
2360
- }));
2361
- let mut mock = build_mock_pollers(mh);
2362
- mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
2363
- let core = mock_worker(mock);
2364
-
2365
- let act = core.poll_workflow_activation().await.unwrap();
2366
- assert_matches!(act.available_internal_flags.as_slice(), [1]);
2367
- core.complete_workflow_activation(WorkflowActivationCompletion::empty(act.run_id))
2368
- .await
2369
- .unwrap();
2370
-
2371
- let act = core.poll_workflow_activation().await.unwrap();
2372
- let mut completion = WorkflowActivationCompletion::empty(act.run_id);
2373
- completion.add_internal_flags(2);
2374
- core.complete_workflow_activation(completion).await.unwrap();
2375
-
2376
- let act = core.poll_workflow_activation().await.unwrap();
2377
- assert_matches!(act.available_internal_flags.as_slice(), [1, 2]);
2378
- core.complete_execution(&act.run_id).await;
2379
- core.shutdown().await;
2380
- }
2381
-
2382
- // Verify we send flags to server when they're used
2383
- #[tokio::test]
2384
- async fn core_internal_flags() {
2385
- let mut t = TestHistoryBuilder::default();
2386
- t.add_by_type(EventType::WorkflowExecutionStarted);
2387
- t.add_full_wf_task();
2388
- let act_scheduled_event_id = t.add_activity_task_scheduled("act-id");
2389
- let act_started_event_id = t.add_activity_task_started(act_scheduled_event_id);
2390
- t.add_activity_task_completed(
2391
- act_scheduled_event_id,
2392
- act_started_event_id,
2393
- Default::default(),
2394
- );
2395
- t.add_full_wf_task();
2396
- t.add_workflow_execution_completed();
2397
-
2398
- let mut mh = MockPollCfg::from_resp_batches(
2399
- "fake_wf_id",
2400
- t,
2401
- [ResponseType::ToTaskNum(1), ResponseType::ToTaskNum(2)],
2402
- mock_workflow_client(),
2403
- );
2404
- let first_poll = AtomicBool::new(true);
2405
- mh.completion_asserts = Some(Box::new(move |c| {
2406
- if !first_poll.load(Ordering::Acquire) {
2407
- assert_matches!(c.sdk_metadata.core_used_flags.as_slice(), &[1]);
2408
- }
2409
- first_poll.store(false, Ordering::Release);
2410
- }));
2411
- let mut mock = build_mock_pollers(mh);
2412
- mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
2413
- let core = mock_worker(mock);
2414
-
2415
- let act = core.poll_workflow_activation().await.unwrap();
2416
- core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
2417
- act.run_id,
2418
- schedule_activity_cmd(
2419
- 1,
2420
- "whatever",
2421
- "act-id",
2422
- ActivityCancellationType::TryCancel,
2423
- Duration::from_secs(60),
2424
- Duration::from_secs(60),
2425
- ),
2426
- ))
2427
- .await
2428
- .unwrap();
2429
-
2430
- let act = core.poll_workflow_activation().await.unwrap();
2431
- core.complete_execution(&act.run_id).await;
2432
- core.shutdown().await;
2433
- }