temporalio 0.1.1 → 0.2.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 (585) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +4035 -0
  3. data/Cargo.toml +25 -0
  4. data/Gemfile +20 -0
  5. data/LICENSE +16 -15
  6. data/README.md +455 -195
  7. data/Rakefile +387 -0
  8. data/ext/Cargo.toml +25 -0
  9. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  10. data/lib/temporalio/activity/context.rb +82 -77
  11. data/lib/temporalio/activity/definition.rb +77 -0
  12. data/lib/temporalio/activity/info.rb +42 -46
  13. data/lib/temporalio/activity.rb +49 -65
  14. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  15. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +93 -0
  16. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  17. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  18. data/lib/temporalio/api/cloud/identity/v1/message.rb +36 -0
  19. data/lib/temporalio/api/cloud/namespace/v1/message.rb +35 -0
  20. data/lib/temporalio/api/cloud/operation/v1/message.rb +27 -0
  21. data/lib/temporalio/api/cloud/region/v1/message.rb +23 -0
  22. data/lib/temporalio/api/command/v1/message.rb +46 -0
  23. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  24. data/lib/temporalio/api/common/v1/message.rb +41 -0
  25. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  26. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  27. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  28. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  29. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  30. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  31. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  32. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  33. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  34. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  35. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  36. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  37. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  38. data/lib/temporalio/api/export/v1/message.rb +24 -0
  39. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  40. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  41. data/lib/temporalio/api/history/v1/message.rb +90 -0
  42. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  43. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  44. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  45. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  46. data/lib/temporalio/api/operatorservice.rb +3 -0
  47. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  48. data/lib/temporalio/api/query/v1/message.rb +27 -0
  49. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  50. data/lib/temporalio/api/schedule/v1/message.rb +42 -0
  51. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  52. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  53. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  54. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  55. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  56. data/lib/temporalio/api/update/v1/message.rb +33 -0
  57. data/lib/temporalio/api/version/v1/message.rb +26 -0
  58. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  59. data/lib/temporalio/api/workflowservice/v1/request_response.rb +189 -0
  60. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  61. data/lib/temporalio/api/workflowservice.rb +3 -0
  62. data/lib/temporalio/api.rb +13 -0
  63. data/lib/temporalio/cancellation.rb +150 -0
  64. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  65. data/lib/temporalio/client/async_activity_handle.rb +110 -0
  66. data/lib/temporalio/client/connection/cloud_service.rb +648 -0
  67. data/lib/temporalio/client/connection/operator_service.rb +249 -0
  68. data/lib/temporalio/client/connection/service.rb +41 -0
  69. data/lib/temporalio/client/connection/workflow_service.rb +1218 -0
  70. data/lib/temporalio/client/connection.rb +270 -0
  71. data/lib/temporalio/client/interceptor.rb +316 -0
  72. data/lib/temporalio/client/workflow_execution.rb +103 -0
  73. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  74. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  75. data/lib/temporalio/client/workflow_handle.rb +380 -177
  76. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  77. data/lib/temporalio/client/workflow_update_handle.rb +67 -0
  78. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  79. data/lib/temporalio/client.rb +366 -93
  80. data/lib/temporalio/common_enums.rb +24 -0
  81. data/lib/temporalio/converters/data_converter.rb +102 -0
  82. data/lib/temporalio/converters/failure_converter.rb +200 -0
  83. data/lib/temporalio/converters/payload_codec.rb +26 -0
  84. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  85. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  86. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  87. data/lib/temporalio/converters/payload_converter/composite.rb +62 -0
  88. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  89. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  90. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  91. data/lib/temporalio/converters/payload_converter.rb +73 -0
  92. data/lib/temporalio/converters.rb +9 -0
  93. data/lib/temporalio/error/failure.rb +119 -94
  94. data/lib/temporalio/error.rb +147 -0
  95. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  96. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  97. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  98. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  99. data/lib/temporalio/internal/bridge/api/core_interface.rb +36 -0
  100. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  101. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +52 -0
  102. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +54 -0
  103. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  104. data/lib/temporalio/internal/bridge/api.rb +3 -0
  105. data/lib/temporalio/internal/bridge/client.rb +90 -0
  106. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  107. data/lib/temporalio/internal/bridge/testing.rb +46 -0
  108. data/lib/temporalio/internal/bridge/worker.rb +83 -0
  109. data/lib/temporalio/internal/bridge.rb +36 -0
  110. data/lib/temporalio/internal/client/implementation.rb +525 -0
  111. data/lib/temporalio/internal/proto_utils.rb +54 -0
  112. data/lib/temporalio/internal/worker/activity_worker.rb +345 -0
  113. data/lib/temporalio/internal/worker/multi_runner.rb +169 -0
  114. data/lib/temporalio/internal.rb +7 -0
  115. data/lib/temporalio/retry_policy.rb +39 -80
  116. data/lib/temporalio/runtime.rb +259 -13
  117. data/lib/temporalio/scoped_logger.rb +96 -0
  118. data/lib/temporalio/search_attributes.rb +300 -0
  119. data/lib/temporalio/testing/activity_environment.rb +132 -0
  120. data/lib/temporalio/testing/workflow_environment.rb +113 -88
  121. data/lib/temporalio/testing.rb +4 -169
  122. data/lib/temporalio/version.rb +3 -1
  123. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  124. data/lib/temporalio/worker/activity_executor/thread_pool.rb +254 -0
  125. data/lib/temporalio/worker/activity_executor.rb +55 -0
  126. data/lib/temporalio/worker/interceptor.rb +88 -0
  127. data/lib/temporalio/worker/tuner.rb +151 -0
  128. data/lib/temporalio/worker.rb +385 -163
  129. data/lib/temporalio/workflow_history.rb +22 -0
  130. data/lib/temporalio.rb +2 -7
  131. data/temporalio.gemspec +20 -39
  132. metadata +131 -712
  133. data/bridge/Cargo.lock +0 -2997
  134. data/bridge/Cargo.toml +0 -29
  135. data/bridge/sdk-core/ARCHITECTURE.md +0 -76
  136. data/bridge/sdk-core/Cargo.toml +0 -2
  137. data/bridge/sdk-core/LICENSE.txt +0 -23
  138. data/bridge/sdk-core/README.md +0 -117
  139. data/bridge/sdk-core/arch_docs/diagrams/README.md +0 -10
  140. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +0 -40
  141. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  142. data/bridge/sdk-core/arch_docs/sticky_queues.md +0 -51
  143. data/bridge/sdk-core/client/Cargo.toml +0 -40
  144. data/bridge/sdk-core/client/LICENSE.txt +0 -23
  145. data/bridge/sdk-core/client/src/lib.rs +0 -1462
  146. data/bridge/sdk-core/client/src/metrics.rs +0 -174
  147. data/bridge/sdk-core/client/src/raw.rs +0 -932
  148. data/bridge/sdk-core/client/src/retry.rs +0 -763
  149. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +0 -185
  150. data/bridge/sdk-core/core/Cargo.toml +0 -129
  151. data/bridge/sdk-core/core/LICENSE.txt +0 -23
  152. data/bridge/sdk-core/core/benches/workflow_replay.rs +0 -76
  153. data/bridge/sdk-core/core/src/abstractions.rs +0 -355
  154. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +0 -1049
  155. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +0 -221
  156. data/bridge/sdk-core/core/src/core_tests/determinism.rs +0 -270
  157. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +0 -1046
  158. data/bridge/sdk-core/core/src/core_tests/mod.rs +0 -100
  159. data/bridge/sdk-core/core/src/core_tests/queries.rs +0 -893
  160. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +0 -65
  161. data/bridge/sdk-core/core/src/core_tests/workers.rs +0 -257
  162. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +0 -124
  163. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +0 -2433
  164. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +0 -609
  165. data/bridge/sdk-core/core/src/internal_flags.rs +0 -136
  166. data/bridge/sdk-core/core/src/lib.rs +0 -289
  167. data/bridge/sdk-core/core/src/pollers/mod.rs +0 -54
  168. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +0 -297
  169. data/bridge/sdk-core/core/src/protosext/mod.rs +0 -428
  170. data/bridge/sdk-core/core/src/replay/mod.rs +0 -215
  171. data/bridge/sdk-core/core/src/retry_logic.rs +0 -202
  172. data/bridge/sdk-core/core/src/telemetry/log_export.rs +0 -190
  173. data/bridge/sdk-core/core/src/telemetry/metrics.rs +0 -462
  174. data/bridge/sdk-core/core/src/telemetry/mod.rs +0 -423
  175. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +0 -83
  176. data/bridge/sdk-core/core/src/test_help/mod.rs +0 -939
  177. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +0 -536
  178. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +0 -89
  179. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +0 -1278
  180. data/bridge/sdk-core/core/src/worker/activities.rs +0 -557
  181. data/bridge/sdk-core/core/src/worker/client/mocks.rs +0 -107
  182. data/bridge/sdk-core/core/src/worker/client.rs +0 -389
  183. data/bridge/sdk-core/core/src/worker/mod.rs +0 -677
  184. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +0 -35
  185. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +0 -99
  186. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +0 -1111
  187. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +0 -964
  188. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -294
  189. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -168
  190. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +0 -918
  191. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -137
  192. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -158
  193. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -130
  194. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -1525
  195. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -324
  196. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -179
  197. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -659
  198. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -439
  199. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +0 -435
  200. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +0 -175
  201. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +0 -249
  202. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +0 -85
  203. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +0 -1280
  204. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +0 -269
  205. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +0 -213
  206. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +0 -1305
  207. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +0 -1276
  208. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +0 -128
  209. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +0 -125
  210. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +0 -85
  211. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  212. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  213. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +0 -715
  214. data/bridge/sdk-core/core-api/Cargo.toml +0 -33
  215. data/bridge/sdk-core/core-api/LICENSE.txt +0 -23
  216. data/bridge/sdk-core/core-api/src/errors.rs +0 -62
  217. data/bridge/sdk-core/core-api/src/lib.rs +0 -113
  218. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -141
  219. data/bridge/sdk-core/core-api/src/worker.rs +0 -161
  220. data/bridge/sdk-core/etc/deps.svg +0 -162
  221. data/bridge/sdk-core/etc/dynamic-config.yaml +0 -2
  222. data/bridge/sdk-core/etc/otel-collector-config.yaml +0 -36
  223. data/bridge/sdk-core/etc/prometheus.yaml +0 -6
  224. data/bridge/sdk-core/etc/regen-depgraph.sh +0 -5
  225. data/bridge/sdk-core/fsm/Cargo.toml +0 -18
  226. data/bridge/sdk-core/fsm/LICENSE.txt +0 -23
  227. data/bridge/sdk-core/fsm/README.md +0 -3
  228. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +0 -27
  229. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +0 -23
  230. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +0 -650
  231. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +0 -8
  232. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +0 -18
  233. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +0 -12
  234. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +0 -41
  235. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +0 -14
  236. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +0 -11
  237. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +0 -32
  238. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +0 -31
  239. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +0 -46
  240. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +0 -29
  241. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +0 -12
  242. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +0 -32
  243. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +0 -18
  244. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +0 -5
  245. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +0 -11
  246. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +0 -5
  247. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +0 -11
  248. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +0 -5
  249. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +0 -14
  250. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +0 -23
  251. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +0 -254
  252. data/bridge/sdk-core/fsm/src/lib.rs +0 -2
  253. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  254. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  255. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  256. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  257. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  258. data/bridge/sdk-core/integ-with-otel.sh +0 -7
  259. data/bridge/sdk-core/protos/api_upstream/README.md +0 -9
  260. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +0 -40
  261. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -9
  262. data/bridge/sdk-core/protos/api_upstream/build/go.mod +0 -7
  263. data/bridge/sdk-core/protos/api_upstream/build/go.sum +0 -5
  264. data/bridge/sdk-core/protos/api_upstream/build/tools.go +0 -29
  265. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +0 -141
  266. data/bridge/sdk-core/protos/api_upstream/go.mod +0 -6
  267. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +0 -89
  268. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +0 -248
  269. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +0 -123
  270. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -47
  271. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +0 -52
  272. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +0 -56
  273. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +0 -170
  274. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +0 -123
  275. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +0 -51
  276. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +0 -50
  277. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +0 -41
  278. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +0 -60
  279. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -59
  280. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +0 -56
  281. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +0 -122
  282. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +0 -108
  283. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +0 -114
  284. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +0 -56
  285. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +0 -787
  286. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +0 -99
  287. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +0 -124
  288. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -80
  289. data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +0 -57
  290. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +0 -61
  291. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +0 -55
  292. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +0 -379
  293. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +0 -63
  294. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +0 -108
  295. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +0 -111
  296. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +0 -59
  297. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +0 -146
  298. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +0 -1199
  299. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +0 -415
  300. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +0 -63
  301. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +0 -79
  302. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +0 -80
  303. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -78
  304. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -16
  305. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +0 -31
  306. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +0 -31
  307. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +0 -270
  308. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +0 -305
  309. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -35
  310. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +0 -38
  311. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +0 -13
  312. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +0 -141
  313. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -63
  314. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -90
  315. data/bridge/sdk-core/rustfmt.toml +0 -1
  316. data/bridge/sdk-core/sdk/Cargo.toml +0 -48
  317. data/bridge/sdk-core/sdk/LICENSE.txt +0 -23
  318. data/bridge/sdk-core/sdk/src/activity_context.rs +0 -230
  319. data/bridge/sdk-core/sdk/src/app_data.rs +0 -37
  320. data/bridge/sdk-core/sdk/src/interceptors.rs +0 -50
  321. data/bridge/sdk-core/sdk/src/lib.rs +0 -861
  322. data/bridge/sdk-core/sdk/src/payload_converter.rs +0 -11
  323. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +0 -295
  324. data/bridge/sdk-core/sdk/src/workflow_context.rs +0 -694
  325. data/bridge/sdk-core/sdk/src/workflow_future.rs +0 -500
  326. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +0 -33
  327. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +0 -23
  328. data/bridge/sdk-core/sdk-core-protos/build.rs +0 -142
  329. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +0 -7
  330. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +0 -557
  331. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +0 -234
  332. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +0 -2088
  333. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +0 -48
  334. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +0 -14
  335. data/bridge/sdk-core/test-utils/Cargo.toml +0 -38
  336. data/bridge/sdk-core/test-utils/src/canned_histories.rs +0 -1389
  337. data/bridge/sdk-core/test-utils/src/histfetch.rs +0 -28
  338. data/bridge/sdk-core/test-utils/src/lib.rs +0 -709
  339. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  340. data/bridge/sdk-core/test-utils/src/workflows.rs +0 -29
  341. data/bridge/sdk-core/tests/fuzzy_workflow.rs +0 -130
  342. data/bridge/sdk-core/tests/heavy_tests.rs +0 -265
  343. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +0 -36
  344. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +0 -150
  345. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +0 -223
  346. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +0 -239
  347. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -90
  348. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +0 -314
  349. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +0 -151
  350. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +0 -902
  351. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
  352. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +0 -60
  353. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +0 -51
  354. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +0 -51
  355. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +0 -64
  356. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -47
  357. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +0 -669
  358. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +0 -54
  359. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +0 -92
  360. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +0 -228
  361. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +0 -94
  362. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +0 -171
  363. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +0 -85
  364. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +0 -120
  365. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +0 -77
  366. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +0 -596
  367. data/bridge/sdk-core/tests/main.rs +0 -103
  368. data/bridge/sdk-core/tests/runner.rs +0 -132
  369. data/bridge/sdk-core/tests/wf_input_replay.rs +0 -32
  370. data/bridge/src/connection.rs +0 -202
  371. data/bridge/src/lib.rs +0 -494
  372. data/bridge/src/runtime.rs +0 -54
  373. data/bridge/src/test_server.rs +0 -153
  374. data/bridge/src/worker.rs +0 -197
  375. data/ext/Rakefile +0 -9
  376. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +0 -14
  377. data/lib/gen/temporal/api/batch/v1/message_pb.rb +0 -50
  378. data/lib/gen/temporal/api/command/v1/message_pb.rb +0 -160
  379. data/lib/gen/temporal/api/common/v1/message_pb.rb +0 -73
  380. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +0 -33
  381. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +0 -37
  382. data/lib/gen/temporal/api/enums/v1/common_pb.rb +0 -42
  383. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +0 -68
  384. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +0 -79
  385. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +0 -37
  386. data/lib/gen/temporal/api/enums/v1/query_pb.rb +0 -31
  387. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +0 -24
  388. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +0 -28
  389. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +0 -30
  390. data/lib/gen/temporal/api/enums/v1/update_pb.rb +0 -25
  391. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +0 -89
  392. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +0 -84
  393. data/lib/gen/temporal/api/failure/v1/message_pb.rb +0 -83
  394. data/lib/gen/temporal/api/filter/v1/message_pb.rb +0 -40
  395. data/lib/gen/temporal/api/history/v1/message_pb.rb +0 -498
  396. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +0 -64
  397. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +0 -88
  398. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +0 -20
  399. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +0 -30
  400. data/lib/gen/temporal/api/query/v1/message_pb.rb +0 -38
  401. data/lib/gen/temporal/api/replication/v1/message_pb.rb +0 -37
  402. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +0 -149
  403. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +0 -23
  404. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +0 -73
  405. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +0 -49
  406. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +0 -21
  407. data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -72
  408. data/lib/gen/temporal/api/version/v1/message_pb.rb +0 -41
  409. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +0 -111
  410. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +0 -798
  411. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +0 -20
  412. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +0 -62
  413. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +0 -61
  414. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +0 -61
  415. data/lib/gen/temporal/sdk/core/common/common_pb.rb +0 -26
  416. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +0 -40
  417. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +0 -31
  418. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +0 -171
  419. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +0 -200
  420. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +0 -41
  421. data/lib/temporalio/bridge/connect_options.rb +0 -15
  422. data/lib/temporalio/bridge/error.rb +0 -8
  423. data/lib/temporalio/bridge/retry_config.rb +0 -24
  424. data/lib/temporalio/bridge/tls_options.rb +0 -19
  425. data/lib/temporalio/bridge.rb +0 -14
  426. data/lib/temporalio/client/implementation.rb +0 -340
  427. data/lib/temporalio/connection/retry_config.rb +0 -44
  428. data/lib/temporalio/connection/service.rb +0 -20
  429. data/lib/temporalio/connection/test_service.rb +0 -92
  430. data/lib/temporalio/connection/tls_options.rb +0 -51
  431. data/lib/temporalio/connection/workflow_service.rb +0 -731
  432. data/lib/temporalio/connection.rb +0 -86
  433. data/lib/temporalio/data_converter.rb +0 -191
  434. data/lib/temporalio/error/workflow_failure.rb +0 -19
  435. data/lib/temporalio/errors.rb +0 -40
  436. data/lib/temporalio/failure_converter/base.rb +0 -26
  437. data/lib/temporalio/failure_converter/basic.rb +0 -319
  438. data/lib/temporalio/failure_converter.rb +0 -7
  439. data/lib/temporalio/interceptor/activity_inbound.rb +0 -22
  440. data/lib/temporalio/interceptor/activity_outbound.rb +0 -24
  441. data/lib/temporalio/interceptor/chain.rb +0 -28
  442. data/lib/temporalio/interceptor/client.rb +0 -127
  443. data/lib/temporalio/interceptor.rb +0 -22
  444. data/lib/temporalio/payload_codec/base.rb +0 -32
  445. data/lib/temporalio/payload_converter/base.rb +0 -24
  446. data/lib/temporalio/payload_converter/bytes.rb +0 -27
  447. data/lib/temporalio/payload_converter/composite.rb +0 -49
  448. data/lib/temporalio/payload_converter/encoding_base.rb +0 -35
  449. data/lib/temporalio/payload_converter/json.rb +0 -26
  450. data/lib/temporalio/payload_converter/nil.rb +0 -26
  451. data/lib/temporalio/payload_converter.rb +0 -14
  452. data/lib/temporalio/retry_state.rb +0 -35
  453. data/lib/temporalio/testing/time_skipping_handle.rb +0 -32
  454. data/lib/temporalio/testing/time_skipping_interceptor.rb +0 -23
  455. data/lib/temporalio/timeout_type.rb +0 -29
  456. data/lib/temporalio/worker/activity_runner.rb +0 -114
  457. data/lib/temporalio/worker/activity_worker.rb +0 -164
  458. data/lib/temporalio/worker/reactor.rb +0 -46
  459. data/lib/temporalio/worker/runner.rb +0 -63
  460. data/lib/temporalio/worker/sync_worker.rb +0 -124
  461. data/lib/temporalio/worker/thread_pool_executor.rb +0 -51
  462. data/lib/temporalio/workflow/async.rb +0 -46
  463. data/lib/temporalio/workflow/execution_info.rb +0 -54
  464. data/lib/temporalio/workflow/execution_status.rb +0 -36
  465. data/lib/temporalio/workflow/future.rb +0 -138
  466. data/lib/temporalio/workflow/id_reuse_policy.rb +0 -36
  467. data/lib/temporalio/workflow/info.rb +0 -76
  468. data/lib/temporalio/workflow/query_reject_condition.rb +0 -33
  469. data/lib/thermite_patch.rb +0 -33
  470. data/sig/async.rbs +0 -17
  471. data/sig/protobuf.rbs +0 -16
  472. data/sig/protos/dependencies/gogoproto/gogo.rbs +0 -914
  473. data/sig/protos/google/protobuf/any.rbs +0 -157
  474. data/sig/protos/google/protobuf/descriptor.rbs +0 -2825
  475. data/sig/protos/google/protobuf/duration.rbs +0 -114
  476. data/sig/protos/google/protobuf/empty.rbs +0 -36
  477. data/sig/protos/google/protobuf/timestamp.rbs +0 -145
  478. data/sig/protos/google/protobuf/wrappers.rbs +0 -358
  479. data/sig/protos/temporal/api/batch/v1/message.rbs +0 -300
  480. data/sig/protos/temporal/api/command/v1/message.rbs +0 -1399
  481. data/sig/protos/temporal/api/common/v1/message.rbs +0 -528
  482. data/sig/protos/temporal/api/enums/v1/batch_operation.rbs +0 -79
  483. data/sig/protos/temporal/api/enums/v1/command_type.rbs +0 -68
  484. data/sig/protos/temporal/api/enums/v1/common.rbs +0 -118
  485. data/sig/protos/temporal/api/enums/v1/event_type.rbs +0 -264
  486. data/sig/protos/temporal/api/enums/v1/failed_cause.rbs +0 -277
  487. data/sig/protos/temporal/api/enums/v1/namespace.rbs +0 -108
  488. data/sig/protos/temporal/api/enums/v1/query.rbs +0 -81
  489. data/sig/protos/temporal/api/enums/v1/reset.rbs +0 -44
  490. data/sig/protos/temporal/api/enums/v1/schedule.rbs +0 -72
  491. data/sig/protos/temporal/api/enums/v1/task_queue.rbs +0 -92
  492. data/sig/protos/temporal/api/enums/v1/update.rbs +0 -64
  493. data/sig/protos/temporal/api/enums/v1/workflow.rbs +0 -371
  494. data/sig/protos/temporal/api/errordetails/v1/message.rbs +0 -551
  495. data/sig/protos/temporal/api/failure/v1/message.rbs +0 -581
  496. data/sig/protos/temporal/api/filter/v1/message.rbs +0 -171
  497. data/sig/protos/temporal/api/history/v1/message.rbs +0 -4609
  498. data/sig/protos/temporal/api/namespace/v1/message.rbs +0 -410
  499. data/sig/protos/temporal/api/operatorservice/v1/request_response.rbs +0 -643
  500. data/sig/protos/temporal/api/operatorservice/v1/service.rbs +0 -17
  501. data/sig/protos/temporal/api/protocol/v1/message.rbs +0 -84
  502. data/sig/protos/temporal/api/query/v1/message.rbs +0 -182
  503. data/sig/protos/temporal/api/replication/v1/message.rbs +0 -148
  504. data/sig/protos/temporal/api/schedule/v1/message.rbs +0 -1488
  505. data/sig/protos/temporal/api/sdk/v1/task_complete_metadata.rbs +0 -110
  506. data/sig/protos/temporal/api/taskqueue/v1/message.rbs +0 -486
  507. data/sig/protos/temporal/api/testservice/v1/request_response.rbs +0 -249
  508. data/sig/protos/temporal/api/testservice/v1/service.rbs +0 -15
  509. data/sig/protos/temporal/api/update/v1/message.rbs +0 -489
  510. data/sig/protos/temporal/api/version/v1/message.rbs +0 -184
  511. data/sig/protos/temporal/api/workflow/v1/message.rbs +0 -824
  512. data/sig/protos/temporal/api/workflowservice/v1/request_response.rbs +0 -7250
  513. data/sig/protos/temporal/api/workflowservice/v1/service.rbs +0 -22
  514. data/sig/protos/temporal/sdk/core/activity_result/activity_result.rbs +0 -380
  515. data/sig/protos/temporal/sdk/core/activity_task/activity_task.rbs +0 -386
  516. data/sig/protos/temporal/sdk/core/child_workflow/child_workflow.rbs +0 -323
  517. data/sig/protos/temporal/sdk/core/common/common.rbs +0 -62
  518. data/sig/protos/temporal/sdk/core/core_interface.rbs +0 -101
  519. data/sig/protos/temporal/sdk/core/external_data/external_data.rbs +0 -119
  520. data/sig/protos/temporal/sdk/core/workflow_activation/workflow_activation.rbs +0 -1473
  521. data/sig/protos/temporal/sdk/core/workflow_commands/workflow_commands.rbs +0 -1784
  522. data/sig/protos/temporal/sdk/core/workflow_completion/workflow_completion.rbs +0 -180
  523. data/sig/ruby.rbs +0 -12
  524. data/sig/temporalio/activity/context.rbs +0 -29
  525. data/sig/temporalio/activity/info.rbs +0 -43
  526. data/sig/temporalio/activity.rbs +0 -19
  527. data/sig/temporalio/bridge/connect_options.rbs +0 -19
  528. data/sig/temporalio/bridge/error.rbs +0 -8
  529. data/sig/temporalio/bridge/retry_config.rbs +0 -21
  530. data/sig/temporalio/bridge/tls_options.rbs +0 -17
  531. data/sig/temporalio/bridge.rbs +0 -71
  532. data/sig/temporalio/client/implementation.rbs +0 -38
  533. data/sig/temporalio/client/workflow_handle.rbs +0 -41
  534. data/sig/temporalio/client.rbs +0 -35
  535. data/sig/temporalio/connection/retry_config.rbs +0 -37
  536. data/sig/temporalio/connection/service.rbs +0 -14
  537. data/sig/temporalio/connection/test_service.rbs +0 -13
  538. data/sig/temporalio/connection/tls_options.rbs +0 -43
  539. data/sig/temporalio/connection/workflow_service.rbs +0 -48
  540. data/sig/temporalio/connection.rbs +0 -30
  541. data/sig/temporalio/data_converter.rbs +0 -35
  542. data/sig/temporalio/error/failure.rbs +0 -121
  543. data/sig/temporalio/error/workflow_failure.rbs +0 -9
  544. data/sig/temporalio/errors.rbs +0 -36
  545. data/sig/temporalio/failure_converter/base.rbs +0 -12
  546. data/sig/temporalio/failure_converter/basic.rbs +0 -86
  547. data/sig/temporalio/failure_converter.rbs +0 -5
  548. data/sig/temporalio/interceptor/activity_inbound.rbs +0 -21
  549. data/sig/temporalio/interceptor/activity_outbound.rbs +0 -10
  550. data/sig/temporalio/interceptor/chain.rbs +0 -24
  551. data/sig/temporalio/interceptor/client.rbs +0 -148
  552. data/sig/temporalio/interceptor.rbs +0 -6
  553. data/sig/temporalio/payload_codec/base.rbs +0 -12
  554. data/sig/temporalio/payload_converter/base.rbs +0 -12
  555. data/sig/temporalio/payload_converter/bytes.rbs +0 -9
  556. data/sig/temporalio/payload_converter/composite.rbs +0 -19
  557. data/sig/temporalio/payload_converter/encoding_base.rbs +0 -14
  558. data/sig/temporalio/payload_converter/json.rbs +0 -9
  559. data/sig/temporalio/payload_converter/nil.rbs +0 -9
  560. data/sig/temporalio/payload_converter.rbs +0 -5
  561. data/sig/temporalio/retry_policy.rbs +0 -25
  562. data/sig/temporalio/retry_state.rbs +0 -20
  563. data/sig/temporalio/runtime.rbs +0 -12
  564. data/sig/temporalio/testing/time_skipping_handle.rbs +0 -15
  565. data/sig/temporalio/testing/time_skipping_interceptor.rbs +0 -13
  566. data/sig/temporalio/testing/workflow_environment.rbs +0 -22
  567. data/sig/temporalio/testing.rbs +0 -35
  568. data/sig/temporalio/timeout_type.rbs +0 -15
  569. data/sig/temporalio/version.rbs +0 -3
  570. data/sig/temporalio/worker/activity_runner.rbs +0 -35
  571. data/sig/temporalio/worker/activity_worker.rbs +0 -44
  572. data/sig/temporalio/worker/reactor.rbs +0 -22
  573. data/sig/temporalio/worker/runner.rbs +0 -21
  574. data/sig/temporalio/worker/sync_worker.rbs +0 -23
  575. data/sig/temporalio/worker/thread_pool_executor.rbs +0 -23
  576. data/sig/temporalio/worker.rbs +0 -46
  577. data/sig/temporalio/workflow/async.rbs +0 -9
  578. data/sig/temporalio/workflow/execution_info.rbs +0 -55
  579. data/sig/temporalio/workflow/execution_status.rbs +0 -21
  580. data/sig/temporalio/workflow/future.rbs +0 -40
  581. data/sig/temporalio/workflow/id_reuse_policy.rbs +0 -15
  582. data/sig/temporalio/workflow/info.rbs +0 -55
  583. data/sig/temporalio/workflow/query_reject_condition.rbs +0 -14
  584. data/sig/temporalio.rbs +0 -2
  585. 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
- }