temporalio 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +180 -7
  3. data/bridge/Cargo.lock +208 -76
  4. data/bridge/Cargo.toml +5 -2
  5. data/bridge/sdk-core/Cargo.toml +1 -1
  6. data/bridge/sdk-core/README.md +20 -10
  7. data/bridge/sdk-core/client/Cargo.toml +1 -1
  8. data/bridge/sdk-core/client/src/lib.rs +227 -59
  9. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  10. data/bridge/sdk-core/client/src/raw.rs +13 -12
  11. data/bridge/sdk-core/client/src/retry.rs +132 -43
  12. data/bridge/sdk-core/core/Cargo.toml +28 -15
  13. data/bridge/sdk-core/core/benches/workflow_replay.rs +13 -10
  14. data/bridge/sdk-core/core/src/abstractions.rs +225 -36
  15. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +217 -79
  16. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  17. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +565 -34
  18. data/bridge/sdk-core/core/src/core_tests/queries.rs +247 -90
  19. data/bridge/sdk-core/core/src/core_tests/workers.rs +3 -5
  20. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  21. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +430 -67
  22. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  23. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  24. data/bridge/sdk-core/core/src/lib.rs +148 -34
  25. data/bridge/sdk-core/core/src/protosext/mod.rs +1 -1
  26. data/bridge/sdk-core/core/src/replay/mod.rs +185 -41
  27. data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
  28. data/bridge/sdk-core/core/src/telemetry/metrics.rs +219 -140
  29. data/bridge/sdk-core/core/src/telemetry/mod.rs +326 -315
  30. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +20 -14
  31. data/bridge/sdk-core/core/src/test_help/mod.rs +85 -21
  32. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  33. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  34. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +364 -128
  35. data/bridge/sdk-core/core/src/worker/activities.rs +263 -170
  36. data/bridge/sdk-core/core/src/worker/client/mocks.rs +23 -3
  37. data/bridge/sdk-core/core/src/worker/client.rs +48 -6
  38. data/bridge/sdk-core/core/src/worker/mod.rs +186 -75
  39. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  40. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +13 -24
  41. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +879 -226
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +101 -48
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +8 -12
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -9
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +90 -32
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +6 -9
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +7 -10
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +6 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +160 -83
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +36 -54
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +179 -0
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +104 -157
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +8 -12
  54. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -13
  55. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +10 -4
  56. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -11
  57. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
  58. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +395 -299
  59. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +12 -20
  60. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +33 -18
  61. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1032 -374
  62. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +525 -392
  63. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  64. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  65. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +3 -6
  66. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  67. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  68. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +456 -681
  69. data/bridge/sdk-core/core-api/Cargo.toml +6 -4
  70. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  71. data/bridge/sdk-core/core-api/src/lib.rs +7 -45
  72. data/bridge/sdk-core/core-api/src/telemetry.rs +141 -0
  73. data/bridge/sdk-core/core-api/src/worker.rs +27 -1
  74. data/bridge/sdk-core/etc/deps.svg +115 -140
  75. data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
  76. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  77. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  78. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  79. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  80. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  81. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  82. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -3
  83. data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
  84. data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
  85. data/bridge/sdk-core/protos/api_upstream/{temporal/api/enums/v1/cluster.proto → build/tools.go} +7 -18
  86. data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
  87. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -9
  88. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +15 -26
  89. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
  90. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  91. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +4 -9
  92. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  93. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +10 -8
  94. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +28 -2
  95. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  96. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  97. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  98. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  99. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  100. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +24 -19
  101. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  102. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  103. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  104. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  105. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +62 -26
  106. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +4 -2
  107. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +24 -61
  108. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -21
  109. data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +57 -0
  110. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  111. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  112. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +110 -31
  113. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  114. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +4 -4
  115. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +71 -6
  116. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  117. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +3 -2
  118. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +111 -36
  119. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +19 -5
  120. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  121. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  122. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  123. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  124. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  125. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  126. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +9 -0
  127. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +9 -1
  128. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  129. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  130. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  131. data/bridge/sdk-core/sdk/Cargo.toml +4 -3
  132. data/bridge/sdk-core/sdk/src/interceptors.rs +36 -3
  133. data/bridge/sdk-core/sdk/src/lib.rs +94 -25
  134. data/bridge/sdk-core/sdk/src/workflow_context.rs +13 -2
  135. data/bridge/sdk-core/sdk/src/workflow_future.rs +10 -13
  136. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  137. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -2
  138. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +164 -104
  139. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +27 -23
  140. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +252 -74
  141. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  142. data/bridge/sdk-core/test-utils/Cargo.toml +4 -1
  143. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  144. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  145. data/bridge/sdk-core/test-utils/src/lib.rs +161 -50
  146. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  147. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  148. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  149. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  150. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  151. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +10 -5
  152. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +239 -0
  153. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -60
  154. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  155. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  156. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  157. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  158. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  159. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  160. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  161. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  162. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +151 -116
  163. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +54 -0
  164. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  165. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +115 -24
  166. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  167. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  168. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  169. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  170. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  171. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +27 -18
  172. data/bridge/sdk-core/tests/main.rs +8 -16
  173. data/bridge/sdk-core/tests/runner.rs +75 -36
  174. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  175. data/bridge/src/connection.rs +117 -82
  176. data/bridge/src/lib.rs +356 -42
  177. data/bridge/src/runtime.rs +10 -3
  178. data/bridge/src/test_server.rs +153 -0
  179. data/bridge/src/worker.rs +133 -9
  180. data/lib/gen/temporal/api/batch/v1/message_pb.rb +8 -6
  181. data/lib/gen/temporal/api/command/v1/message_pb.rb +10 -16
  182. data/lib/gen/temporal/api/common/v1/message_pb.rb +5 -1
  183. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +2 -1
  184. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +3 -3
  185. data/lib/gen/temporal/api/enums/v1/common_pb.rb +2 -1
  186. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +5 -4
  187. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +9 -1
  188. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +1 -1
  189. data/lib/gen/temporal/api/enums/v1/query_pb.rb +1 -1
  190. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +1 -1
  191. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +1 -1
  192. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +1 -1
  193. data/lib/gen/temporal/api/enums/v1/update_pb.rb +7 -10
  194. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +1 -1
  195. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +1 -1
  196. data/lib/gen/temporal/api/failure/v1/message_pb.rb +1 -1
  197. data/lib/gen/temporal/api/filter/v1/message_pb.rb +1 -1
  198. data/lib/gen/temporal/api/history/v1/message_pb.rb +34 -25
  199. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +2 -1
  200. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +14 -51
  201. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +1 -1
  202. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  203. data/lib/gen/temporal/api/query/v1/message_pb.rb +1 -1
  204. data/lib/gen/temporal/api/replication/v1/message_pb.rb +1 -1
  205. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +22 -1
  206. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  207. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +2 -2
  208. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  209. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  210. data/lib/gen/temporal/api/update/v1/message_pb.rb +49 -3
  211. data/lib/gen/temporal/api/version/v1/message_pb.rb +1 -1
  212. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +2 -1
  213. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +47 -20
  214. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +1 -1
  215. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  216. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  217. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  218. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  219. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  220. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  221. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +28 -21
  222. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +32 -24
  223. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  224. data/lib/temporalio/activity/context.rb +102 -0
  225. data/lib/temporalio/activity/info.rb +67 -0
  226. data/lib/temporalio/activity.rb +85 -0
  227. data/lib/temporalio/bridge/connect_options.rb +15 -0
  228. data/lib/temporalio/bridge/error.rb +8 -0
  229. data/lib/temporalio/bridge/retry_config.rb +24 -0
  230. data/lib/temporalio/bridge/tls_options.rb +19 -0
  231. data/lib/temporalio/bridge.rb +14 -0
  232. data/lib/{temporal → temporalio}/client/implementation.rb +57 -56
  233. data/lib/{temporal → temporalio}/client/workflow_handle.rb +35 -35
  234. data/lib/{temporal → temporalio}/client.rb +19 -32
  235. data/lib/temporalio/connection/retry_config.rb +44 -0
  236. data/lib/temporalio/connection/service.rb +20 -0
  237. data/lib/temporalio/connection/test_service.rb +92 -0
  238. data/lib/temporalio/connection/tls_options.rb +51 -0
  239. data/lib/temporalio/connection/workflow_service.rb +731 -0
  240. data/lib/temporalio/connection.rb +86 -0
  241. data/lib/{temporal → temporalio}/data_converter.rb +76 -35
  242. data/lib/{temporal → temporalio}/error/failure.rb +6 -6
  243. data/lib/{temporal → temporalio}/error/workflow_failure.rb +4 -2
  244. data/lib/{temporal → temporalio}/errors.rb +19 -1
  245. data/lib/{temporal → temporalio}/failure_converter/base.rb +5 -5
  246. data/lib/{temporal → temporalio}/failure_converter/basic.rb +58 -52
  247. data/lib/temporalio/failure_converter.rb +7 -0
  248. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  249. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  250. data/lib/{temporal → temporalio}/interceptor/chain.rb +7 -6
  251. data/lib/{temporal → temporalio}/interceptor/client.rb +27 -2
  252. data/lib/temporalio/interceptor.rb +22 -0
  253. data/lib/{temporal → temporalio}/payload_codec/base.rb +5 -5
  254. data/lib/{temporal → temporalio}/payload_converter/base.rb +3 -3
  255. data/lib/{temporal → temporalio}/payload_converter/bytes.rb +4 -3
  256. data/lib/{temporal → temporalio}/payload_converter/composite.rb +7 -5
  257. data/lib/{temporal → temporalio}/payload_converter/encoding_base.rb +4 -4
  258. data/lib/{temporal → temporalio}/payload_converter/json.rb +4 -3
  259. data/lib/{temporal → temporalio}/payload_converter/nil.rb +4 -3
  260. data/lib/temporalio/payload_converter.rb +14 -0
  261. data/lib/{temporal → temporalio}/retry_policy.rb +17 -7
  262. data/lib/{temporal → temporalio}/retry_state.rb +1 -1
  263. data/lib/temporalio/runtime.rb +25 -0
  264. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  265. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  266. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  267. data/lib/temporalio/testing.rb +175 -0
  268. data/lib/{temporal → temporalio}/timeout_type.rb +2 -2
  269. data/lib/temporalio/version.rb +3 -0
  270. data/lib/temporalio/worker/activity_runner.rb +114 -0
  271. data/lib/temporalio/worker/activity_worker.rb +164 -0
  272. data/lib/temporalio/worker/reactor.rb +46 -0
  273. data/lib/temporalio/worker/runner.rb +63 -0
  274. data/lib/temporalio/worker/sync_worker.rb +124 -0
  275. data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
  276. data/lib/temporalio/worker.rb +204 -0
  277. data/lib/temporalio/workflow/async.rb +46 -0
  278. data/lib/{temporal → temporalio}/workflow/execution_info.rb +4 -4
  279. data/lib/{temporal → temporalio}/workflow/execution_status.rb +1 -1
  280. data/lib/temporalio/workflow/future.rb +138 -0
  281. data/lib/{temporal → temporalio}/workflow/id_reuse_policy.rb +6 -6
  282. data/lib/temporalio/workflow/info.rb +76 -0
  283. data/lib/{temporal → temporalio}/workflow/query_reject_condition.rb +5 -5
  284. data/lib/temporalio.rb +12 -3
  285. data/temporalio.gemspec +11 -6
  286. metadata +137 -64
  287. data/bridge/sdk-core/Cargo.lock +0 -2606
  288. data/bridge/sdk-core/bridge-ffi/Cargo.toml +0 -24
  289. data/bridge/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  290. data/bridge/sdk-core/bridge-ffi/build.rs +0 -25
  291. data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -249
  292. data/bridge/sdk-core/bridge-ffi/src/lib.rs +0 -825
  293. data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +0 -211
  294. data/bridge/sdk-core/core/src/log_export.rs +0 -62
  295. data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
  296. data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
  297. data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
  298. data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  299. data/bridge/sdk-core/sdk/src/conversions.rs +0 -8
  300. data/lib/bridge.so +0 -0
  301. data/lib/gen/temporal/api/cluster/v1/message_pb.rb +0 -67
  302. data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +0 -26
  303. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
  304. data/lib/temporal/bridge.rb +0 -14
  305. data/lib/temporal/connection.rb +0 -736
  306. data/lib/temporal/failure_converter.rb +0 -8
  307. data/lib/temporal/payload_converter.rb +0 -14
  308. data/lib/temporal/runtime.rb +0 -22
  309. data/lib/temporal/version.rb +0 -3
  310. data/lib/temporal.rb +0 -8
@@ -1,17 +1,17 @@
1
- use assert_matches::assert_matches;
2
1
  use futures::{future::join_all, sink, stream::FuturesUnordered, StreamExt};
3
2
  use std::time::{Duration, Instant};
4
3
  use temporal_client::{WfClientExt, WorkflowClientTrait, WorkflowOptions};
5
- use temporal_sdk::{ActContext, ActivityOptions, WfContext};
4
+ use temporal_sdk::{ActContext, ActivityOptions, WfContext, WorkflowResult};
6
5
  use temporal_sdk_core_protos::coresdk::{
7
- activity_result::ActivityExecutionResult, activity_task::activity_task as act_task,
8
- workflow_commands::ActivityCancellationType, ActivityTaskCompletion, AsJsonPayloadExt,
6
+ workflow_commands::ActivityCancellationType, AsJsonPayloadExt,
9
7
  };
10
- use temporal_sdk_core_test_utils::CoreWfStarter;
8
+ use temporal_sdk_core_test_utils::{workflows::la_problem_workflow, CoreWfStarter};
9
+
10
+ mod fuzzy_workflow;
11
11
 
12
12
  #[tokio::test]
13
13
  async fn activity_load() {
14
- const CONCURRENCY: usize = 1000;
14
+ const CONCURRENCY: usize = 512;
15
15
 
16
16
  let mut starter = CoreWfStarter::new("activity_load");
17
17
  starter
@@ -23,18 +23,16 @@ async fn activity_load() {
23
23
 
24
24
  let activity_id = "act-1";
25
25
  let activity_timeout = Duration::from_secs(8);
26
- let payload_dat = b"hello".to_vec();
27
26
  let task_queue = starter.get_task_queue().to_owned();
28
27
 
29
- let pd = payload_dat.clone();
30
28
  let wf_fn = move |ctx: WfContext| {
31
29
  let task_queue = task_queue.clone();
32
- let payload_dat = pd.clone();
33
-
30
+ let payload = "yo".as_json_payload().unwrap();
34
31
  async move {
35
32
  let activity = ActivityOptions {
36
33
  activity_id: Some(activity_id.to_string()),
37
34
  activity_type: "test_activity".to_string(),
35
+ input: payload.clone(),
38
36
  task_queue,
39
37
  schedule_to_start_timeout: Some(activity_timeout),
40
38
  start_to_close_timeout: Some(activity_timeout),
@@ -44,7 +42,7 @@ async fn activity_load() {
44
42
  ..Default::default()
45
43
  };
46
44
  let res = ctx.activity(activity).await.unwrap_ok_payload();
47
- assert_eq!(res.data, payload_dat);
45
+ assert_eq!(res.data, payload.data);
48
46
  Ok(().into())
49
47
  }
50
48
  };
@@ -52,9 +50,13 @@ async fn activity_load() {
52
50
  let starting = Instant::now();
53
51
  let wf_type = "activity_load";
54
52
  worker.register_wf(wf_type.to_owned(), wf_fn);
53
+ worker.register_activity(
54
+ "test_activity",
55
+ |_ctx: ActContext, echo: String| async move { Ok(echo) },
56
+ );
55
57
  join_all((0..CONCURRENCY).map(|i| {
56
58
  let worker = &worker;
57
- let wf_id = format!("activity_load_{}", i);
59
+ let wf_id = format!("activity_load_{i}");
58
60
  async move {
59
61
  worker
60
62
  .submit_wf(
@@ -71,42 +73,8 @@ async fn activity_load() {
71
73
  dbg!(starting.elapsed());
72
74
 
73
75
  let running = Instant::now();
74
- let core = starter.get_worker().await;
75
-
76
- // Poll for and complete all activities
77
- let c2 = core.clone();
78
- let all_acts = async move {
79
- let mut act_complete_futs = vec![];
80
- for _ in 0..CONCURRENCY {
81
- let task = c2.poll_activity_task().await.unwrap();
82
- assert_matches!(
83
- task.variant,
84
- Some(act_task::Variant::Start(ref start_activity)) => {
85
- assert_eq!(start_activity.activity_type, "test_activity")
86
- }
87
- );
88
- let pd = payload_dat.clone();
89
- let core = c2.clone();
90
- act_complete_futs.push(tokio::spawn(async move {
91
- core.complete_activity_task(ActivityTaskCompletion {
92
- task_token: task.task_token,
93
- result: Some(ActivityExecutionResult::ok(pd.into())),
94
- })
95
- .await
96
- .unwrap()
97
- }));
98
- }
99
- join_all(act_complete_futs)
100
- .await
101
- .into_iter()
102
- .for_each(|h| h.unwrap());
103
- };
104
- tokio::join! {
105
- async {
106
- worker.run_until_done().await.unwrap();
107
- },
108
- all_acts
109
- };
76
+
77
+ worker.run_until_done().await.unwrap();
110
78
  dbg!(running.elapsed());
111
79
  }
112
80
 
@@ -153,7 +121,7 @@ async fn workflow_load() {
153
121
 
154
122
  let mut workflow_handles = vec![];
155
123
  for i in 0..num_workflows {
156
- let wfid = format!("{}_{}", wf_name, i);
124
+ let wfid = format!("{wf_name}_{i}");
157
125
  let rid = worker
158
126
  .submit_wf(
159
127
  wfid.clone(),
@@ -171,7 +139,7 @@ async fn workflow_load() {
171
139
  let sends: FuturesUnordered<_> = (0..num_workflows)
172
140
  .map(|i| {
173
141
  client.signal_workflow_execution(
174
- format!("{}_{}", wf_name, i),
142
+ format!("{wf_name}_{i}"),
175
143
  "".to_string(),
176
144
  SIGNAME.to_string(),
177
145
  None,
@@ -187,5 +155,111 @@ async fn workflow_load() {
187
155
  tokio::time::sleep(Duration::from_secs(2)).await;
188
156
  }
189
157
  };
190
- tokio::select! { r1 = worker.run_until_done() => {r1.unwrap()}, _ = sig_sender => {}};
158
+ tokio::select! { r1 = worker.run_until_done() => {r1.unwrap()}, _ = sig_sender => {}}
159
+ }
160
+
161
+ #[tokio::test(flavor = "multi_thread", worker_threads = 4)]
162
+ async fn evict_while_la_running_no_interference() {
163
+ let wf_name = "evict_while_la_running_no_interference";
164
+ let mut starter = CoreWfStarter::new(wf_name);
165
+ starter.max_local_at(20);
166
+ starter.max_cached_workflows(20);
167
+ // Though it doesn't make sense to set wft higher than cached workflows, leaving this commented
168
+ // introduces more instability that can be useful in the test.
169
+ // starter.max_wft(20);
170
+ let mut worker = starter.worker().await;
171
+
172
+ worker.register_wf(wf_name.to_owned(), la_problem_workflow);
173
+ worker.register_activity("delay", |_: ActContext, _: String| async {
174
+ tokio::time::sleep(Duration::from_secs(15)).await;
175
+ Ok(())
176
+ });
177
+
178
+ let client = starter.get_client().await;
179
+ let subfs = FuturesUnordered::new();
180
+ for i in 1..100 {
181
+ let wf_id = format!("{wf_name}-{i}");
182
+ let run_id = worker
183
+ .submit_wf(
184
+ &wf_id,
185
+ wf_name.to_owned(),
186
+ vec![],
187
+ WorkflowOptions::default(),
188
+ )
189
+ .await
190
+ .unwrap();
191
+ let cw = worker.core_worker.clone();
192
+ let client = client.clone();
193
+ subfs.push(async move {
194
+ // Evict the workflow
195
+ tokio::time::sleep(Duration::from_secs(1)).await;
196
+ cw.request_workflow_eviction(&run_id);
197
+ // Wake up workflow by sending signal
198
+ client
199
+ .signal_workflow_execution(
200
+ wf_id,
201
+ run_id.clone(),
202
+ "whaatever".to_string(),
203
+ None,
204
+ None,
205
+ )
206
+ .await
207
+ .unwrap();
208
+ });
209
+ }
210
+ let runf = async {
211
+ worker.run_until_done().await.unwrap();
212
+ };
213
+ tokio::join!(subfs.collect::<Vec<_>>(), runf);
214
+ }
215
+
216
+ pub async fn many_parallel_timers_longhist(ctx: WfContext) -> WorkflowResult<()> {
217
+ for _ in 0..120 {
218
+ let mut futs = vec![];
219
+ for _ in 0..100 {
220
+ futs.push(ctx.timer(Duration::from_millis(100)));
221
+ }
222
+ join_all(futs).await;
223
+ }
224
+ Ok(().into())
225
+ }
226
+
227
+ #[tokio::test]
228
+ async fn can_paginate_long_history() {
229
+ let wf_name = "can_paginate_long_history";
230
+ let mut starter = CoreWfStarter::new(wf_name);
231
+ starter.no_remote_activities();
232
+ // Do not use sticky queues so we are forced to paginate once history gets long
233
+ starter.max_cached_workflows(0);
234
+
235
+ let mut worker = starter.worker().await;
236
+ worker.register_wf(wf_name.to_owned(), many_parallel_timers_longhist);
237
+ let run_id = worker
238
+ .submit_wf(
239
+ wf_name.to_owned(),
240
+ wf_name.to_owned(),
241
+ vec![],
242
+ WorkflowOptions::default(),
243
+ )
244
+ .await
245
+ .unwrap();
246
+ let client = starter.get_client().await;
247
+ tokio::spawn(async move {
248
+ loop {
249
+ for _ in 0..10 {
250
+ client
251
+ .signal_workflow_execution(
252
+ wf_name.to_owned(),
253
+ run_id.clone(),
254
+ "sig".to_string(),
255
+ None,
256
+ None,
257
+ )
258
+ .await
259
+ .unwrap();
260
+ }
261
+ tokio::time::sleep(Duration::from_secs(3)).await;
262
+ }
263
+ });
264
+ worker.run_until_done().await.unwrap();
191
265
  }
@@ -1,13 +1,35 @@
1
1
  use std::time::{SystemTime, UNIX_EPOCH};
2
2
  use temporal_client::{ClientOptionsBuilder, TestService, WorkflowService};
3
3
  use temporal_sdk_core::ephemeral_server::{
4
- EphemeralExe, EphemeralExeVersion, EphemeralServer, TemporaliteConfigBuilder,
5
- TestServerConfigBuilder,
4
+ EphemeralExe, EphemeralExeVersion, EphemeralServer, TemporalDevServerConfigBuilder,
5
+ TemporaliteConfigBuilder, TestServerConfigBuilder,
6
6
  };
7
7
  use temporal_sdk_core_protos::temporal::api::workflowservice::v1::DescribeNamespaceRequest;
8
8
  use temporal_sdk_core_test_utils::{default_cached_download, NAMESPACE};
9
9
  use url::Url;
10
10
 
11
+ #[tokio::test]
12
+ async fn temporal_cli_default() {
13
+ let config = TemporalDevServerConfigBuilder::default()
14
+ .exe(default_cached_download())
15
+ .build()
16
+ .unwrap();
17
+ let mut server = config.start_server().await.unwrap();
18
+ assert_ephemeral_server(&server).await;
19
+ server.shutdown().await.unwrap();
20
+ }
21
+
22
+ #[tokio::test]
23
+ async fn temporal_cli_fixed() {
24
+ let config = TemporalDevServerConfigBuilder::default()
25
+ .exe(fixed_cached_download("v0.4.0"))
26
+ .build()
27
+ .unwrap();
28
+ let mut server = config.start_server().await.unwrap();
29
+ assert_ephemeral_server(&server).await;
30
+ server.shutdown().await.unwrap();
31
+ }
32
+
11
33
  #[tokio::test]
12
34
  async fn temporalite_default() {
13
35
  let config = TemporaliteConfigBuilder::default()
@@ -22,7 +44,7 @@ async fn temporalite_default() {
22
44
  #[tokio::test]
23
45
  async fn temporalite_fixed() {
24
46
  let config = TemporaliteConfigBuilder::default()
25
- .exe(fixed_cached_download("v0.1.1"))
47
+ .exe(fixed_cached_download("v0.2.0"))
26
48
  .build()
27
49
  .unwrap();
28
50
  let mut server = config.start_server().await.unwrap();
@@ -13,10 +13,15 @@ use temporal_sdk_core_protos::{
13
13
  workflow_completion::WorkflowActivationCompletion,
14
14
  ActivityHeartbeat, ActivityTaskCompletion, AsJsonPayloadExt, IntoCompletion,
15
15
  },
16
- temporal::api::common::v1::{Payload, RetryPolicy},
16
+ temporal::api::{
17
+ common::v1::{Payload, RetryPolicy},
18
+ enums::v1::TimeoutType,
19
+ },
20
+ DEFAULT_ACTIVITY_TYPE,
17
21
  };
18
22
  use temporal_sdk_core_test_utils::{
19
- init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
23
+ drain_pollers_and_shutdown, init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter,
24
+ WorkerTestHelpers,
20
25
  };
21
26
  use tokio::time::sleep;
22
27
 
@@ -46,7 +51,7 @@ async fn activity_heartbeat() {
46
51
  assert_matches!(
47
52
  task.variant,
48
53
  Some(activity_task::Variant::Start(start_activity)) => {
49
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
54
+ assert_eq!(start_activity.activity_type, DEFAULT_ACTIVITY_TYPE.to_string())
50
55
  }
51
56
  );
52
57
  // Heartbeat timeout is set to 1 second, this loop is going to send heartbeat every 100ms.
@@ -166,7 +171,7 @@ async fn many_act_fails_with_heartbeats() {
166
171
  },]
167
172
  );
168
173
  core.complete_execution(&task.run_id).await;
169
- core.shutdown().await;
174
+ drain_pollers_and_shutdown(&core).await;
170
175
  }
171
176
 
172
177
  #[tokio::test]
@@ -196,7 +201,7 @@ async fn activity_doesnt_heartbeat_hits_timeout_then_completes() {
196
201
  ..Default::default()
197
202
  })
198
203
  .await;
199
- assert!(res.timed_out());
204
+ assert_eq!(res.timed_out(), Some(TimeoutType::Heartbeat));
200
205
  Ok(().into())
201
206
  });
202
207
 
@@ -0,0 +1,239 @@
1
+ use std::{sync::Arc, time::Duration};
2
+ use temporal_client::{WorkflowClientTrait, WorkflowOptions, WorkflowService};
3
+ use temporal_sdk_core::{init_worker, CoreRuntime};
4
+ use temporal_sdk_core_api::{telemetry::MetricsExporter, worker::WorkerConfigBuilder, Worker};
5
+ use temporal_sdk_core_protos::{
6
+ coresdk::{
7
+ activity_result::ActivityExecutionResult,
8
+ workflow_commands::{ScheduleActivity, ScheduleLocalActivity},
9
+ workflow_completion::WorkflowActivationCompletion,
10
+ ActivityTaskCompletion,
11
+ },
12
+ temporal::api::{enums::v1::WorkflowIdReusePolicy, workflowservice::v1::ListNamespacesRequest},
13
+ };
14
+ use temporal_sdk_core_test_utils::{get_integ_server_options, get_integ_telem_options, NAMESPACE};
15
+ use tokio::sync::Barrier;
16
+
17
+ static ANY_PORT: &str = "127.0.0.1:0";
18
+
19
+ async fn get_text(endpoint: String) -> String {
20
+ reqwest::get(endpoint).await.unwrap().text().await.unwrap()
21
+ }
22
+
23
+ #[tokio::test]
24
+ async fn prometheus_metrics_exported() {
25
+ let mut telemopts = get_integ_telem_options();
26
+ telemopts.metrics = Some(MetricsExporter::Prometheus(ANY_PORT.parse().unwrap()));
27
+ let rt = CoreRuntime::new_assume_tokio(telemopts).unwrap();
28
+ let addr = rt.telemetry().prom_port().unwrap();
29
+ let opts = get_integ_server_options();
30
+ let mut raw_client = opts
31
+ .connect_no_namespace(rt.metric_meter().as_deref(), None)
32
+ .await
33
+ .unwrap();
34
+ assert!(raw_client.get_client().capabilities().is_some());
35
+
36
+ let _ = raw_client
37
+ .list_namespaces(ListNamespacesRequest::default())
38
+ .await
39
+ .unwrap();
40
+
41
+ let body = get_text(format!("http://{addr}/metrics")).await;
42
+ assert!(body.contains(
43
+ "temporal_request_latency_count{operation=\"ListNamespaces\",service_name=\"temporal-core-sdk\"} 1"
44
+ ));
45
+ assert!(body.contains(
46
+ "temporal_request_latency_count{operation=\"GetSystemInfo\",service_name=\"temporal-core-sdk\"} 1"
47
+ ));
48
+ }
49
+
50
+ #[tokio::test]
51
+ async fn one_slot_worker_reports_available_slot() {
52
+ let mut telemopts = get_integ_telem_options();
53
+ let tq = "one_slot_worker_tq";
54
+ telemopts.metrics = Some(MetricsExporter::Prometheus(ANY_PORT.parse().unwrap()));
55
+ let rt = CoreRuntime::new_assume_tokio(telemopts).unwrap();
56
+ let addr = rt.telemetry().prom_port().unwrap();
57
+
58
+ let worker_cfg = WorkerConfigBuilder::default()
59
+ .namespace(NAMESPACE)
60
+ .task_queue(tq)
61
+ .worker_build_id("test_build_id")
62
+ .max_cached_workflows(1_usize)
63
+ .max_outstanding_activities(1_usize)
64
+ .max_outstanding_local_activities(1_usize)
65
+ .max_outstanding_workflow_tasks(1_usize)
66
+ .build()
67
+ .unwrap();
68
+
69
+ let client = Arc::new(
70
+ get_integ_server_options()
71
+ .connect(worker_cfg.namespace.clone(), None, None)
72
+ .await
73
+ .expect("Must connect"),
74
+ );
75
+ let worker = init_worker(&rt, worker_cfg, client.clone()).expect("Worker inits cleanly");
76
+ let wf_task_barr = Barrier::new(2);
77
+ let act_task_barr = Barrier::new(2);
78
+
79
+ let wf_polling = async {
80
+ let task = worker.poll_workflow_activation().await.unwrap();
81
+ wf_task_barr.wait().await;
82
+ wf_task_barr.wait().await;
83
+ worker
84
+ .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
85
+ task.run_id,
86
+ ScheduleActivity {
87
+ seq: 1,
88
+ activity_id: "1".to_string(),
89
+ activity_type: "test_act".to_string(),
90
+ task_queue: tq.to_string(),
91
+ start_to_close_timeout: Some(prost_dur!(from_secs(30))),
92
+ ..Default::default()
93
+ }
94
+ .into(),
95
+ ))
96
+ .await
97
+ .unwrap();
98
+ wf_task_barr.wait().await;
99
+
100
+ let task = worker.poll_workflow_activation().await.unwrap();
101
+ worker
102
+ .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
103
+ task.run_id,
104
+ ScheduleLocalActivity {
105
+ seq: 2,
106
+ activity_id: "2".to_string(),
107
+ activity_type: "test_act".to_string(),
108
+ start_to_close_timeout: Some(prost_dur!(from_secs(30))),
109
+ ..Default::default()
110
+ }
111
+ .into(),
112
+ ))
113
+ .await
114
+ .unwrap();
115
+ };
116
+
117
+ let act_polling = async {
118
+ let task = worker.poll_activity_task().await.unwrap();
119
+ act_task_barr.wait().await;
120
+ worker
121
+ .complete_activity_task(ActivityTaskCompletion {
122
+ task_token: task.task_token,
123
+ result: Some(ActivityExecutionResult::ok(vec![1].into())),
124
+ })
125
+ .await
126
+ .unwrap();
127
+ act_task_barr.wait().await;
128
+
129
+ let task = worker.poll_activity_task().await.unwrap();
130
+ act_task_barr.wait().await;
131
+ act_task_barr.wait().await;
132
+ worker
133
+ .complete_activity_task(ActivityTaskCompletion {
134
+ task_token: task.task_token,
135
+ result: Some(ActivityExecutionResult::ok(vec![1].into())),
136
+ })
137
+ .await
138
+ .unwrap();
139
+ act_task_barr.wait().await;
140
+ };
141
+
142
+ let testing = async {
143
+ // Wait just a beat for the poller to initiate
144
+ tokio::time::sleep(Duration::from_millis(50)).await;
145
+ let body = get_text(format!("http://{addr}/metrics")).await;
146
+ assert!(body.contains(&format!(
147
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
148
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
149
+ worker_type=\"WorkflowWorker\"}} 1"
150
+ )));
151
+
152
+ // Start a workflow so that a task will get delivered
153
+ client
154
+ .start_workflow(
155
+ vec![],
156
+ tq.to_owned(),
157
+ "one_slot_metric_test".to_owned(),
158
+ "whatever".to_string(),
159
+ None,
160
+ WorkflowOptions {
161
+ id_reuse_policy: WorkflowIdReusePolicy::TerminateIfRunning,
162
+ execution_timeout: Some(Duration::from_secs(5)),
163
+ ..Default::default()
164
+ },
165
+ )
166
+ .await
167
+ .unwrap();
168
+
169
+ wf_task_barr.wait().await;
170
+
171
+ // At this point the workflow task is outstanding, so there should be 0 slots, and
172
+ // the activities haven't started, so there should be 1 each.
173
+ let body = get_text(format!("http://{addr}/metrics")).await;
174
+ assert!(body.contains(&format!(
175
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
176
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
177
+ worker_type=\"WorkflowWorker\"}} 0"
178
+ )));
179
+ assert!(body.contains(&format!(
180
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
181
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
182
+ worker_type=\"ActivityWorker\"}} 1"
183
+ )));
184
+ assert!(body.contains(&format!(
185
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
186
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
187
+ worker_type=\"LocalActivityWorker\"}} 1"
188
+ )));
189
+
190
+ // Now we allow the complete to proceed. Once it goes through, there should be 1 WFT slot
191
+ // open but 0 activity slots
192
+ wf_task_barr.wait().await;
193
+ wf_task_barr.wait().await;
194
+ // Sometimes the recording takes an extra bit. 🤷
195
+ tokio::time::sleep(Duration::from_millis(100)).await;
196
+ let body = get_text(format!("http://{addr}/metrics")).await;
197
+ assert!(body.contains(&format!(
198
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
199
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
200
+ worker_type=\"WorkflowWorker\"}} 1"
201
+ )));
202
+ assert!(body.contains(&format!(
203
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
204
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
205
+ worker_type=\"ActivityWorker\"}} 0"
206
+ )));
207
+
208
+ // Now complete the activity and watch it go up
209
+ act_task_barr.wait().await;
210
+ // Wait for completion to finish
211
+ act_task_barr.wait().await;
212
+ let body = get_text(format!("http://{addr}/metrics")).await;
213
+ assert!(body.contains(&format!(
214
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
215
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
216
+ worker_type=\"ActivityWorker\"}} 1"
217
+ )));
218
+
219
+ // Proceed to local activity command
220
+ act_task_barr.wait().await;
221
+ // Ensure that, once we have the LA task, slots are 0
222
+ let body = get_text(format!("http://{addr}/metrics")).await;
223
+ assert!(body.contains(&format!(
224
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
225
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
226
+ worker_type=\"LocalActivityWorker\"}} 0"
227
+ )));
228
+ // When completion is done, we have 1 again
229
+ act_task_barr.wait().await;
230
+ act_task_barr.wait().await;
231
+ let body = get_text(format!("http://{addr}/metrics")).await;
232
+ assert!(body.contains(&format!(
233
+ "temporal_worker_task_slots_available{{namespace=\"{NAMESPACE}\",\
234
+ service_name=\"temporal-core-sdk\",task_queue=\"one_slot_worker_tq\",\
235
+ worker_type=\"LocalActivityWorker\"}} 1"
236
+ )));
237
+ };
238
+ tokio::join!(wf_polling, act_polling, testing);
239
+ }
@@ -1,9 +1,5 @@
1
1
  use assert_matches::assert_matches;
2
- use futures::future::join_all;
3
2
  use std::time::Duration;
4
- use temporal_client::WorkflowOptions;
5
- use temporal_sdk::{WfContext, WorkflowResult};
6
- use temporal_sdk_core_api::errors::PollWfError;
7
3
  use temporal_sdk_core_protos::coresdk::{
8
4
  activity_task::activity_task as act_task,
9
5
  workflow_activation::{workflow_activation_job, FireTimer, WorkflowActivationJob},
@@ -12,7 +8,7 @@ use temporal_sdk_core_protos::coresdk::{
12
8
  IntoCompletion,
13
9
  };
14
10
  use temporal_sdk_core_test_utils::{
15
- init_core_and_create_wf, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
11
+ init_core_and_create_wf, schedule_activity_cmd, WorkerTestHelpers,
16
12
  };
17
13
  use tokio::time::timeout;
18
14
 
@@ -44,15 +40,10 @@ async fn out_of_order_completion_doesnt_hang() {
44
40
  )
45
41
  .await
46
42
  .unwrap();
47
- // Poll activity and verify that it's been scheduled with correct parameters, we don't expect to
48
- // complete it in this test as activity is try-cancelled.
43
+ // Poll activity and verify that it's been scheduled, we don't expect to complete it in this
44
+ // test as activity is try-cancelled.
49
45
  let activity_task = core.poll_activity_task().await.unwrap();
50
- assert_matches!(
51
- activity_task.variant,
52
- Some(act_task::Variant::Start(start_activity)) => {
53
- assert_eq!(start_activity.activity_type, "test_activity".to_string())
54
- }
55
- );
46
+ assert_matches!(activity_task.variant, Some(act_task::Variant::Start(_)));
56
47
  // Poll workflow task and verify that activity has failed.
57
48
  let task = core.poll_workflow_activation().await.unwrap();
58
49
  assert_matches!(
@@ -97,50 +88,3 @@ async fn out_of_order_completion_doesnt_hang() {
97
88
 
98
89
  jh.await.unwrap();
99
90
  }
100
-
101
- pub async fn many_parallel_timers_longhist(ctx: WfContext) -> WorkflowResult<()> {
102
- for _ in 0..20 {
103
- let mut futs = vec![];
104
- for _ in 0..1000 {
105
- futs.push(ctx.timer(Duration::from_millis(100)));
106
- }
107
- join_all(futs).await;
108
- }
109
- Ok(().into())
110
- }
111
-
112
- // Ignored for now because I can't actually get this to produce pages. Need to generate some
113
- // large payloads I think.
114
- #[tokio::test]
115
- #[ignore]
116
- async fn can_paginate_long_history() {
117
- let wf_name = "can_paginate_long_history";
118
- let mut starter = CoreWfStarter::new(wf_name);
119
- // Do not use sticky queues so we are forced to paginate once history gets long
120
- starter.max_cached_workflows(0);
121
-
122
- let mut worker = starter.worker().await;
123
- worker.register_wf(wf_name.to_owned(), many_parallel_timers_longhist);
124
- worker
125
- .submit_wf(
126
- wf_name.to_owned(),
127
- wf_name.to_owned(),
128
- vec![],
129
- WorkflowOptions::default(),
130
- )
131
- .await
132
- .unwrap();
133
- worker.run_until_done().await.unwrap();
134
- }
135
-
136
- // TODO: Takes ages now, fix somehow
137
- #[tokio::test]
138
- async fn poll_of_nonexistent_namespace_is_fatal() {
139
- let mut starter = CoreWfStarter::new("whatever_yo");
140
- starter.worker_config.namespace = "I do not exist".to_string();
141
- let worker = starter.get_worker().await;
142
- assert_matches!(
143
- worker.poll_workflow_activation().await,
144
- Err(PollWfError::TonicError(_))
145
- );
146
- }