temporalio 0.0.1 → 0.1.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 (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
- }