temporalio 0.0.1

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 (317) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +20 -0
  4. data/README.md +130 -0
  5. data/bridge/Cargo.lock +2865 -0
  6. data/bridge/Cargo.toml +26 -0
  7. data/bridge/sdk-core/ARCHITECTURE.md +76 -0
  8. data/bridge/sdk-core/Cargo.lock +2606 -0
  9. data/bridge/sdk-core/Cargo.toml +2 -0
  10. data/bridge/sdk-core/LICENSE.txt +23 -0
  11. data/bridge/sdk-core/README.md +107 -0
  12. data/bridge/sdk-core/arch_docs/diagrams/README.md +10 -0
  13. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +40 -0
  14. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
  15. data/bridge/sdk-core/arch_docs/sticky_queues.md +51 -0
  16. data/bridge/sdk-core/bridge-ffi/Cargo.toml +24 -0
  17. data/bridge/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  18. data/bridge/sdk-core/bridge-ffi/build.rs +25 -0
  19. data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +249 -0
  20. data/bridge/sdk-core/bridge-ffi/src/lib.rs +825 -0
  21. data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +211 -0
  22. data/bridge/sdk-core/client/Cargo.toml +40 -0
  23. data/bridge/sdk-core/client/LICENSE.txt +23 -0
  24. data/bridge/sdk-core/client/src/lib.rs +1294 -0
  25. data/bridge/sdk-core/client/src/metrics.rs +165 -0
  26. data/bridge/sdk-core/client/src/raw.rs +931 -0
  27. data/bridge/sdk-core/client/src/retry.rs +674 -0
  28. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +185 -0
  29. data/bridge/sdk-core/core/Cargo.toml +116 -0
  30. data/bridge/sdk-core/core/LICENSE.txt +23 -0
  31. data/bridge/sdk-core/core/benches/workflow_replay.rs +73 -0
  32. data/bridge/sdk-core/core/src/abstractions.rs +166 -0
  33. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +911 -0
  34. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +221 -0
  35. data/bridge/sdk-core/core/src/core_tests/determinism.rs +107 -0
  36. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +515 -0
  37. data/bridge/sdk-core/core/src/core_tests/mod.rs +100 -0
  38. data/bridge/sdk-core/core/src/core_tests/queries.rs +736 -0
  39. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +65 -0
  40. data/bridge/sdk-core/core/src/core_tests/workers.rs +259 -0
  41. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +124 -0
  42. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +2070 -0
  43. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
  44. data/bridge/sdk-core/core/src/lib.rs +175 -0
  45. data/bridge/sdk-core/core/src/log_export.rs +62 -0
  46. data/bridge/sdk-core/core/src/pollers/mod.rs +54 -0
  47. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +297 -0
  48. data/bridge/sdk-core/core/src/protosext/mod.rs +428 -0
  49. data/bridge/sdk-core/core/src/replay/mod.rs +71 -0
  50. data/bridge/sdk-core/core/src/retry_logic.rs +202 -0
  51. data/bridge/sdk-core/core/src/telemetry/metrics.rs +383 -0
  52. data/bridge/sdk-core/core/src/telemetry/mod.rs +412 -0
  53. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +77 -0
  54. data/bridge/sdk-core/core/src/test_help/mod.rs +875 -0
  55. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +580 -0
  56. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +1042 -0
  57. data/bridge/sdk-core/core/src/worker/activities.rs +464 -0
  58. data/bridge/sdk-core/core/src/worker/client/mocks.rs +87 -0
  59. data/bridge/sdk-core/core/src/worker/client.rs +347 -0
  60. data/bridge/sdk-core/core/src/worker/mod.rs +566 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +37 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +110 -0
  63. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +458 -0
  64. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +911 -0
  65. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +298 -0
  66. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +171 -0
  67. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +860 -0
  68. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +140 -0
  69. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +161 -0
  70. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +133 -0
  71. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +1448 -0
  72. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +342 -0
  73. data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +127 -0
  74. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +712 -0
  75. data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +71 -0
  76. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +443 -0
  77. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +439 -0
  78. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +169 -0
  79. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +246 -0
  80. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +96 -0
  81. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +1184 -0
  82. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +277 -0
  83. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
  84. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +647 -0
  85. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +1143 -0
  86. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +145 -0
  87. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
  88. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +940 -0
  89. data/bridge/sdk-core/core-api/Cargo.toml +31 -0
  90. data/bridge/sdk-core/core-api/LICENSE.txt +23 -0
  91. data/bridge/sdk-core/core-api/src/errors.rs +95 -0
  92. data/bridge/sdk-core/core-api/src/lib.rs +151 -0
  93. data/bridge/sdk-core/core-api/src/worker.rs +135 -0
  94. data/bridge/sdk-core/etc/deps.svg +187 -0
  95. data/bridge/sdk-core/etc/dynamic-config.yaml +2 -0
  96. data/bridge/sdk-core/etc/otel-collector-config.yaml +36 -0
  97. data/bridge/sdk-core/etc/prometheus.yaml +6 -0
  98. data/bridge/sdk-core/fsm/Cargo.toml +18 -0
  99. data/bridge/sdk-core/fsm/LICENSE.txt +23 -0
  100. data/bridge/sdk-core/fsm/README.md +3 -0
  101. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +27 -0
  102. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +23 -0
  103. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +647 -0
  104. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +8 -0
  105. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +18 -0
  106. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +12 -0
  107. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +41 -0
  108. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +14 -0
  109. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +11 -0
  110. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +32 -0
  111. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +31 -0
  112. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +46 -0
  113. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +29 -0
  114. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +12 -0
  115. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +32 -0
  116. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +18 -0
  117. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +5 -0
  118. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +11 -0
  119. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +5 -0
  120. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +11 -0
  121. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +5 -0
  122. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +14 -0
  123. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +23 -0
  124. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +249 -0
  125. data/bridge/sdk-core/fsm/src/lib.rs +2 -0
  126. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  127. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  128. data/bridge/sdk-core/integ-with-otel.sh +7 -0
  129. data/bridge/sdk-core/protos/api_upstream/README.md +9 -0
  130. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +40 -0
  131. data/bridge/sdk-core/protos/api_upstream/buf.yaml +12 -0
  132. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +141 -0
  133. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
  134. data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +83 -0
  135. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +259 -0
  136. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +112 -0
  137. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
  138. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +40 -0
  139. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +57 -0
  140. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +55 -0
  141. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +168 -0
  142. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +97 -0
  143. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +51 -0
  144. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +50 -0
  145. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +41 -0
  146. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
  147. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +59 -0
  148. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
  149. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +122 -0
  150. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +108 -0
  151. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +114 -0
  152. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +56 -0
  153. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +751 -0
  154. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +97 -0
  155. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +161 -0
  156. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +99 -0
  157. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +61 -0
  158. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +55 -0
  159. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +300 -0
  160. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +108 -0
  161. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
  162. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +59 -0
  163. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +145 -0
  164. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +1124 -0
  165. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +401 -0
  166. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +63 -0
  167. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  168. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +79 -0
  169. data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +210 -0
  170. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +77 -0
  171. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +15 -0
  172. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +30 -0
  173. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  174. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +261 -0
  175. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +297 -0
  176. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +29 -0
  177. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
  178. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
  179. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
  180. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
  181. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
  182. data/bridge/sdk-core/rustfmt.toml +1 -0
  183. data/bridge/sdk-core/sdk/Cargo.toml +47 -0
  184. data/bridge/sdk-core/sdk/LICENSE.txt +23 -0
  185. data/bridge/sdk-core/sdk/src/activity_context.rs +230 -0
  186. data/bridge/sdk-core/sdk/src/app_data.rs +37 -0
  187. data/bridge/sdk-core/sdk/src/conversions.rs +8 -0
  188. data/bridge/sdk-core/sdk/src/interceptors.rs +17 -0
  189. data/bridge/sdk-core/sdk/src/lib.rs +792 -0
  190. data/bridge/sdk-core/sdk/src/payload_converter.rs +11 -0
  191. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +295 -0
  192. data/bridge/sdk-core/sdk/src/workflow_context.rs +683 -0
  193. data/bridge/sdk-core/sdk/src/workflow_future.rs +503 -0
  194. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +30 -0
  195. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +23 -0
  196. data/bridge/sdk-core/sdk-core-protos/build.rs +108 -0
  197. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  198. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +497 -0
  199. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +230 -0
  200. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +1910 -0
  201. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  202. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  203. data/bridge/sdk-core/test-utils/Cargo.toml +35 -0
  204. data/bridge/sdk-core/test-utils/src/canned_histories.rs +1579 -0
  205. data/bridge/sdk-core/test-utils/src/histfetch.rs +28 -0
  206. data/bridge/sdk-core/test-utils/src/lib.rs +598 -0
  207. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +36 -0
  208. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
  209. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +218 -0
  210. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +146 -0
  211. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +437 -0
  212. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
  213. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +878 -0
  214. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
  215. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +59 -0
  216. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +58 -0
  217. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +50 -0
  218. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +60 -0
  219. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +54 -0
  220. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +634 -0
  221. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +113 -0
  222. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +137 -0
  223. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +93 -0
  224. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +167 -0
  225. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +99 -0
  226. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +131 -0
  227. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +75 -0
  228. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +587 -0
  229. data/bridge/sdk-core/tests/load_tests.rs +191 -0
  230. data/bridge/sdk-core/tests/main.rs +111 -0
  231. data/bridge/sdk-core/tests/runner.rs +93 -0
  232. data/bridge/src/connection.rs +167 -0
  233. data/bridge/src/lib.rs +180 -0
  234. data/bridge/src/runtime.rs +47 -0
  235. data/bridge/src/worker.rs +73 -0
  236. data/ext/Rakefile +9 -0
  237. data/lib/bridge.so +0 -0
  238. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +14 -0
  239. data/lib/gen/temporal/api/batch/v1/message_pb.rb +48 -0
  240. data/lib/gen/temporal/api/cluster/v1/message_pb.rb +67 -0
  241. data/lib/gen/temporal/api/command/v1/message_pb.rb +166 -0
  242. data/lib/gen/temporal/api/common/v1/message_pb.rb +69 -0
  243. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +32 -0
  244. data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +26 -0
  245. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +37 -0
  246. data/lib/gen/temporal/api/enums/v1/common_pb.rb +41 -0
  247. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +67 -0
  248. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +71 -0
  249. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +37 -0
  250. data/lib/gen/temporal/api/enums/v1/query_pb.rb +31 -0
  251. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +24 -0
  252. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +28 -0
  253. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +30 -0
  254. data/lib/gen/temporal/api/enums/v1/update_pb.rb +28 -0
  255. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +89 -0
  256. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +84 -0
  257. data/lib/gen/temporal/api/failure/v1/message_pb.rb +83 -0
  258. data/lib/gen/temporal/api/filter/v1/message_pb.rb +40 -0
  259. data/lib/gen/temporal/api/history/v1/message_pb.rb +489 -0
  260. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +63 -0
  261. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +125 -0
  262. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +20 -0
  263. data/lib/gen/temporal/api/query/v1/message_pb.rb +38 -0
  264. data/lib/gen/temporal/api/replication/v1/message_pb.rb +37 -0
  265. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +128 -0
  266. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +73 -0
  267. data/lib/gen/temporal/api/update/v1/message_pb.rb +26 -0
  268. data/lib/gen/temporal/api/version/v1/message_pb.rb +41 -0
  269. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +110 -0
  270. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +771 -0
  271. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +20 -0
  272. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +58 -0
  273. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +57 -0
  274. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +222 -0
  275. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +57 -0
  276. data/lib/gen/temporal/sdk/core/common/common_pb.rb +22 -0
  277. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +34 -0
  278. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +27 -0
  279. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +164 -0
  280. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +192 -0
  281. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +34 -0
  282. data/lib/temporal/bridge.rb +14 -0
  283. data/lib/temporal/client/implementation.rb +339 -0
  284. data/lib/temporal/client/workflow_handle.rb +243 -0
  285. data/lib/temporal/client.rb +144 -0
  286. data/lib/temporal/connection.rb +736 -0
  287. data/lib/temporal/data_converter.rb +150 -0
  288. data/lib/temporal/error/failure.rb +194 -0
  289. data/lib/temporal/error/workflow_failure.rb +17 -0
  290. data/lib/temporal/errors.rb +22 -0
  291. data/lib/temporal/failure_converter/base.rb +26 -0
  292. data/lib/temporal/failure_converter/basic.rb +313 -0
  293. data/lib/temporal/failure_converter.rb +8 -0
  294. data/lib/temporal/interceptor/chain.rb +27 -0
  295. data/lib/temporal/interceptor/client.rb +102 -0
  296. data/lib/temporal/payload_codec/base.rb +32 -0
  297. data/lib/temporal/payload_converter/base.rb +24 -0
  298. data/lib/temporal/payload_converter/bytes.rb +26 -0
  299. data/lib/temporal/payload_converter/composite.rb +47 -0
  300. data/lib/temporal/payload_converter/encoding_base.rb +35 -0
  301. data/lib/temporal/payload_converter/json.rb +25 -0
  302. data/lib/temporal/payload_converter/nil.rb +25 -0
  303. data/lib/temporal/payload_converter.rb +14 -0
  304. data/lib/temporal/retry_policy.rb +82 -0
  305. data/lib/temporal/retry_state.rb +35 -0
  306. data/lib/temporal/runtime.rb +22 -0
  307. data/lib/temporal/timeout_type.rb +29 -0
  308. data/lib/temporal/version.rb +3 -0
  309. data/lib/temporal/workflow/execution_info.rb +54 -0
  310. data/lib/temporal/workflow/execution_status.rb +36 -0
  311. data/lib/temporal/workflow/id_reuse_policy.rb +36 -0
  312. data/lib/temporal/workflow/query_reject_condition.rb +33 -0
  313. data/lib/temporal.rb +8 -0
  314. data/lib/temporalio.rb +3 -0
  315. data/lib/thermite_patch.rb +23 -0
  316. data/temporalio.gemspec +41 -0
  317. metadata +583 -0
@@ -0,0 +1,185 @@
1
+ use crate::{InterceptedMetricsSvc, RawClientLike};
2
+ use anyhow::{anyhow, bail};
3
+ use std::marker::PhantomData;
4
+ use temporal_sdk_core_protos::{
5
+ coresdk::FromPayloadsExt,
6
+ temporal::api::{
7
+ common::v1::{Payload, WorkflowExecution},
8
+ enums::v1::HistoryEventFilterType,
9
+ failure::v1::Failure,
10
+ history::v1::history_event::Attributes,
11
+ workflowservice::v1::GetWorkflowExecutionHistoryRequest,
12
+ },
13
+ };
14
+
15
+ /// Enumerates terminal states for a particular workflow execution
16
+ // TODO: Add non-proto failure types, flesh out details, etc.
17
+ #[derive(Debug)]
18
+ #[allow(clippy::large_enum_variant)]
19
+ pub enum WorkflowExecutionResult<T> {
20
+ /// The workflow finished successfully
21
+ Succeeded(T),
22
+ /// The workflow finished in failure
23
+ Failed(Failure),
24
+ /// The workflow was cancelled
25
+ Cancelled(Vec<Payload>),
26
+ /// The workflow was terminated
27
+ Terminated(Vec<Payload>),
28
+ /// The workflow timed out
29
+ TimedOut,
30
+ /// The workflow continued as new
31
+ ContinuedAsNew,
32
+ }
33
+
34
+ /// Options for fetching workflow results
35
+ #[derive(Debug, Clone, Copy)]
36
+ pub struct GetWorkflowResultOpts {
37
+ /// If true (the default), follows to the next workflow run in the execution chain while
38
+ /// retrieving results.
39
+ pub follow_runs: bool,
40
+ }
41
+ impl Default for GetWorkflowResultOpts {
42
+ fn default() -> Self {
43
+ Self { follow_runs: true }
44
+ }
45
+ }
46
+
47
+ /// A workflow handle which can refer to a specific workflow run, or a chain of workflow runs with
48
+ /// the same workflow id.
49
+ pub struct WorkflowHandle<ClientT, ResultT> {
50
+ client: ClientT,
51
+ info: WorkflowExecutionInfo,
52
+
53
+ _res_type: PhantomData<ResultT>,
54
+ }
55
+
56
+ /// Holds needed information to refer to a specific workflow run, or workflow execution chain
57
+ pub struct WorkflowExecutionInfo {
58
+ /// Namespace the workflow lives in
59
+ pub namespace: String,
60
+ /// The workflow's id
61
+ pub workflow_id: String,
62
+ /// If set, target this specific run of the workflow
63
+ pub run_id: Option<String>,
64
+ }
65
+
66
+ impl WorkflowExecutionInfo {
67
+ /// Bind the workflow info to a specific client, turning it into a workflow handle
68
+ pub fn bind_untyped<CT>(self, client: CT) -> UntypedWorkflowHandle<CT>
69
+ where
70
+ CT: RawClientLike<SvcType = InterceptedMetricsSvc> + Clone,
71
+ {
72
+ UntypedWorkflowHandle::new(client, self)
73
+ }
74
+ }
75
+
76
+ /// A workflow handle to a workflow with unknown types. Uses raw payloads.
77
+ pub type UntypedWorkflowHandle<CT> = WorkflowHandle<CT, Vec<Payload>>;
78
+
79
+ impl<CT, RT> WorkflowHandle<CT, RT>
80
+ where
81
+ CT: RawClientLike<SvcType = InterceptedMetricsSvc> + Clone,
82
+ // TODO: Make more generic, capable of (de)serialization w/ serde
83
+ RT: FromPayloadsExt,
84
+ {
85
+ pub(crate) fn new(client: CT, info: WorkflowExecutionInfo) -> Self {
86
+ Self {
87
+ client,
88
+ info,
89
+ _res_type: PhantomData::<RT>,
90
+ }
91
+ }
92
+
93
+ pub async fn get_workflow_result(
94
+ &self,
95
+ opts: GetWorkflowResultOpts,
96
+ ) -> Result<WorkflowExecutionResult<RT>, anyhow::Error> {
97
+ let mut next_page_tok = vec![];
98
+ let mut run_id = self.info.run_id.clone().unwrap_or_default();
99
+ loop {
100
+ let server_res = self
101
+ .client
102
+ .clone()
103
+ .workflow_client()
104
+ .get_workflow_execution_history(GetWorkflowExecutionHistoryRequest {
105
+ namespace: self.info.namespace.to_string(),
106
+ execution: Some(WorkflowExecution {
107
+ workflow_id: self.info.workflow_id.clone(),
108
+ run_id: run_id.clone(),
109
+ }),
110
+ skip_archival: true,
111
+ wait_new_event: true,
112
+ history_event_filter_type: HistoryEventFilterType::CloseEvent as i32,
113
+ next_page_token: next_page_tok.clone(),
114
+ ..Default::default()
115
+ })
116
+ .await?
117
+ .into_inner();
118
+
119
+ let mut history = server_res
120
+ .history
121
+ .ok_or_else(|| anyhow!("Server returned an empty history!"))?;
122
+
123
+ if history.events.is_empty() {
124
+ next_page_tok = server_res.next_page_token;
125
+ continue;
126
+ }
127
+ // If page token was previously set, clear it.
128
+ next_page_tok = vec![];
129
+
130
+ let event_attrs = history.events.pop().and_then(|ev| ev.attributes);
131
+
132
+ macro_rules! follow {
133
+ ($attrs:ident) => {
134
+ if opts.follow_runs && $attrs.new_execution_run_id != "" {
135
+ run_id = $attrs.new_execution_run_id;
136
+ continue;
137
+ }
138
+ };
139
+ }
140
+
141
+ break match event_attrs {
142
+ Some(Attributes::WorkflowExecutionCompletedEventAttributes(attrs)) => {
143
+ follow!(attrs);
144
+ Ok(WorkflowExecutionResult::Succeeded(RT::from_payloads(
145
+ attrs.result,
146
+ )))
147
+ }
148
+ Some(Attributes::WorkflowExecutionFailedEventAttributes(attrs)) => {
149
+ follow!(attrs);
150
+ Ok(WorkflowExecutionResult::Failed(
151
+ attrs.failure.unwrap_or_default(),
152
+ ))
153
+ }
154
+ Some(Attributes::WorkflowExecutionCanceledEventAttributes(attrs)) => Ok(
155
+ WorkflowExecutionResult::Cancelled(Vec::from_payloads(attrs.details)),
156
+ ),
157
+ Some(Attributes::WorkflowExecutionTimedOutEventAttributes(attrs)) => {
158
+ follow!(attrs);
159
+ Ok(WorkflowExecutionResult::TimedOut)
160
+ }
161
+ Some(Attributes::WorkflowExecutionTerminatedEventAttributes(attrs)) => Ok(
162
+ WorkflowExecutionResult::Terminated(Vec::from_payloads(attrs.details)),
163
+ ),
164
+ Some(Attributes::WorkflowExecutionContinuedAsNewEventAttributes(attrs)) => {
165
+ if opts.follow_runs {
166
+ if !attrs.new_execution_run_id.is_empty() {
167
+ run_id = attrs.new_execution_run_id;
168
+ continue;
169
+ } else {
170
+ bail!("New execution run id was empty in continue as new event!");
171
+ }
172
+ } else {
173
+ Ok(WorkflowExecutionResult::ContinuedAsNew)
174
+ }
175
+ }
176
+ o => Err(anyhow!(
177
+ "Server returned an event that didn't match the CloseEvent filter. \
178
+ This is either a server bug or a new event the SDK does not understand. \
179
+ Event details: {:?}",
180
+ o
181
+ )),
182
+ };
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,116 @@
1
+ [package]
2
+ name = "temporal-sdk-core"
3
+ version = "0.1.0"
4
+ authors = ["Spencer Judge <spencer@temporal.io>", "Vitaly Arbuzov <vitaly@temporal.io>"]
5
+ edition = "2021"
6
+ license-file = "LICENSE.txt"
7
+ description = "Library for building new Temporal SDKs"
8
+ homepage = "https://temporal.io/"
9
+ repository = "https://github.com/temporalio/sdk-core"
10
+ keywords = ["temporal", "workflow"]
11
+ categories = ["development-tools"]
12
+
13
+ [lib]
14
+
15
+ [dependencies]
16
+ anyhow = "1.0"
17
+ arc-swap = "1.3"
18
+ async-channel = "1.6"
19
+ async-trait = "0.1"
20
+ base64 = "0.13"
21
+ crossbeam = "0.8"
22
+ dashmap = "5.0"
23
+ derive_builder = "0.11"
24
+ derive_more = "0.99"
25
+ enum_dispatch = "0.3"
26
+ flate2 = "1.0"
27
+ futures = "0.3"
28
+ futures-util = "0.3"
29
+ governor = "0.5"
30
+ http = "0.2"
31
+ hyper = "0.14"
32
+ itertools = "0.10"
33
+ lazy_static = "1.4"
34
+ log = "0.4"
35
+ lru = "0.8"
36
+ mockall = "0.11"
37
+ nix = "0.25"
38
+ once_cell = "1.5"
39
+ opentelemetry = { version = "0.18", features = ["rt-tokio"] }
40
+ opentelemetry-otlp = { version = "0.11", features = ["tokio", "metrics"] }
41
+ opentelemetry-prometheus = "0.11"
42
+ parking_lot = { version = "0.12", features = ["send_guard"] }
43
+ prometheus = "0.13"
44
+ prost = "0.11"
45
+ prost-types = "0.11"
46
+ rand = "0.8.3"
47
+ reqwest = { version = "0.11", features = ["json", "stream", "rustls-tls", "tokio-rustls"], default-features = false }
48
+ ringbuf = "0.2"
49
+ serde = "1.0"
50
+ serde_json = "1.0"
51
+ siphasher = "0.3"
52
+ slotmap = "1.0"
53
+ tar = "0.4"
54
+ thiserror = "1.0"
55
+ tokio = { version = "1.1", features = ["rt", "rt-multi-thread", "parking_lot", "time", "fs", "process"] }
56
+ tokio-util = { version = "0.7", features = ["io", "io-util"] }
57
+ tokio-stream = "0.1"
58
+ tonic = { version = "0.8", features = ["tls", "tls-roots"] }
59
+ tracing = { version = "0.1", features = ["log-always"] }
60
+ tracing-futures = "0.2"
61
+ tracing-opentelemetry = "0.18"
62
+ tracing-subscriber = { version = "0.3", features = ["parking_lot", "env-filter"] }
63
+ url = "2.2"
64
+ uuid = { version = "1.1", features = ["v4"] }
65
+ zip = "0.6"
66
+
67
+ # 1st party local deps
68
+ [dependencies.temporal-sdk-core-api]
69
+ path = "../core-api"
70
+ version = "0.1"
71
+
72
+ [dependencies.temporal-sdk-core-protos]
73
+ path = "../sdk-core-protos"
74
+ version = "0.1"
75
+ features = ["history_builders"]
76
+
77
+ [dependencies.temporal-client]
78
+ path = "../client"
79
+ version = "0.1"
80
+
81
+ [dependencies.rustfsm]
82
+ path = "../fsm"
83
+ version = "0.1"
84
+
85
+ [dev-dependencies]
86
+ assert_matches = "1.4"
87
+ bimap = "0.6.1"
88
+ criterion = "0.4"
89
+ rstest = "0.15"
90
+ temporal-sdk-core-test-utils = { path = "../test-utils" }
91
+ temporal-sdk = { path = "../sdk" }
92
+
93
+ [build-dependencies]
94
+ tonic-build = "0.8"
95
+
96
+ [[test]]
97
+ name = "integ_tests"
98
+ path = "../tests/main.rs"
99
+ # Prevents autodiscovery, and hence these getting run with `cargo test`. Run with
100
+ # `cargo test --test integ_tests`
101
+ test = false
102
+
103
+ [[test]]
104
+ name = "load_tests"
105
+ path = "../tests/load_tests.rs"
106
+ test = false
107
+
108
+ [[bench]]
109
+ name = "workflow_replay"
110
+ harness = false
111
+
112
+ # This is maybe a bit hacky, but we call the runner an "example" because that gets it compiling with
113
+ # the dev-dependencies, which we want.
114
+ [[example]]
115
+ name = "integ_runner"
116
+ path = "../tests/runner.rs"
@@ -0,0 +1,23 @@
1
+ Temporal Core SDK
2
+
3
+ The MIT License
4
+
5
+ Copyright (c) 2021 Temporal Technologies, Inc. All Rights Reserved
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
@@ -0,0 +1,73 @@
1
+ use criterion::{criterion_group, criterion_main, Criterion};
2
+ use futures::StreamExt;
3
+ use std::time::Duration;
4
+ use temporal_sdk::{WfContext, Worker, WorkflowFunction};
5
+ use temporal_sdk_core::{telemetry_init, TelemetryOptionsBuilder};
6
+ use temporal_sdk_core_protos::DEFAULT_WORKFLOW_TYPE;
7
+ use temporal_sdk_core_test_utils::{canned_histories, init_core_replay_preloaded};
8
+
9
+ pub fn criterion_benchmark(c: &mut Criterion) {
10
+ let tokio_runtime = tokio::runtime::Builder::new_current_thread()
11
+ .enable_time()
12
+ .build()
13
+ .unwrap();
14
+ telemetry_init(&TelemetryOptionsBuilder::default().build().unwrap()).unwrap();
15
+ let _g = tokio_runtime.enter();
16
+
17
+ let num_timers = 10;
18
+ let t = canned_histories::long_sequential_timers(num_timers as usize);
19
+ let hist = t.get_full_history_info().unwrap().into();
20
+
21
+ c.bench_function("Small history replay", |b| {
22
+ b.iter(|| {
23
+ tokio_runtime.block_on(async {
24
+ let func = timers_wf(num_timers);
25
+ let (worker, _) = init_core_replay_preloaded("replay_bench", &hist);
26
+ let mut worker = Worker::new_from_core(worker, "replay_bench".to_string());
27
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, func);
28
+ worker.run().await.unwrap();
29
+ })
30
+ })
31
+ });
32
+
33
+ let num_tasks = 50;
34
+ let t = canned_histories::lots_of_big_signals(num_tasks);
35
+ let hist = t.get_full_history_info().unwrap().into();
36
+
37
+ c.bench_function("Large payloads history replay", |b| {
38
+ b.iter(|| {
39
+ tokio_runtime.block_on(async {
40
+ let func = big_signals_wf(num_tasks);
41
+ let (worker, _) = init_core_replay_preloaded("large_hist_bench", &hist);
42
+ let mut worker = Worker::new_from_core(worker, "large_hist_bench".to_string());
43
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, func);
44
+ worker.run().await.unwrap();
45
+ })
46
+ })
47
+ });
48
+ }
49
+
50
+ criterion_group!(benches, criterion_benchmark);
51
+ criterion_main!(benches);
52
+
53
+ fn timers_wf(num_timers: u32) -> WorkflowFunction {
54
+ WorkflowFunction::new(move |ctx: WfContext| async move {
55
+ for _ in 1..=num_timers {
56
+ ctx.timer(Duration::from_secs(1)).await;
57
+ }
58
+ Ok(().into())
59
+ })
60
+ }
61
+
62
+ fn big_signals_wf(num_tasks: usize) -> WorkflowFunction {
63
+ WorkflowFunction::new(move |ctx: WfContext| async move {
64
+ let mut sigs = ctx.make_signal_channel("bigsig");
65
+ for _ in 1..=num_tasks {
66
+ for _ in 1..=5 {
67
+ let _ = sigs.next().await.unwrap();
68
+ }
69
+ }
70
+
71
+ Ok(().into())
72
+ })
73
+ }
@@ -0,0 +1,166 @@
1
+ //! This module contains very generic helpers that can be used codebase-wide
2
+
3
+ use crate::MetricsContext;
4
+ use futures::{stream, Stream, StreamExt};
5
+ use std::{
6
+ fmt::{Debug, Formatter},
7
+ future::Future,
8
+ sync::Arc,
9
+ };
10
+ use tokio::sync::{AcquireError, Notify, OwnedSemaphorePermit, Semaphore, TryAcquireError};
11
+
12
+ /// Wraps a [Semaphore] with a function call that is fed the available permits any time a permit is
13
+ /// acquired or restored through the provided methods
14
+ #[derive(Clone)]
15
+ pub(crate) struct MeteredSemaphore {
16
+ sem: Arc<Semaphore>,
17
+ metrics_ctx: MetricsContext,
18
+ record_fn: fn(&MetricsContext, usize),
19
+ }
20
+
21
+ impl MeteredSemaphore {
22
+ pub fn new(
23
+ inital_permits: usize,
24
+ metrics_ctx: MetricsContext,
25
+ record_fn: fn(&MetricsContext, usize),
26
+ ) -> Self {
27
+ Self {
28
+ sem: Arc::new(Semaphore::new(inital_permits)),
29
+ metrics_ctx,
30
+ record_fn,
31
+ }
32
+ }
33
+
34
+ pub fn available_permits(&self) -> usize {
35
+ self.sem.available_permits()
36
+ }
37
+
38
+ pub async fn acquire_owned(&self) -> Result<OwnedMeteredSemPermit, AcquireError> {
39
+ let res = self.sem.clone().acquire_owned().await?;
40
+ self.record();
41
+ Ok(OwnedMeteredSemPermit {
42
+ inner: res,
43
+ record_fn: self.record_drop_owned(),
44
+ })
45
+ }
46
+
47
+ pub fn try_acquire_owned(&self) -> Result<OwnedMeteredSemPermit, TryAcquireError> {
48
+ let res = self.sem.clone().try_acquire_owned()?;
49
+ self.record();
50
+ Ok(OwnedMeteredSemPermit {
51
+ inner: res,
52
+ record_fn: self.record_drop_owned(),
53
+ })
54
+ }
55
+
56
+ fn record(&self) {
57
+ (self.record_fn)(&self.metrics_ctx, self.sem.available_permits());
58
+ }
59
+
60
+ fn record_drop_owned(&self) -> Box<dyn Fn() + Send + Sync> {
61
+ let rcf = self.record_fn;
62
+ let mets = self.metrics_ctx.clone();
63
+ let sem = self.sem.clone();
64
+ Box::new(move || rcf(&mets, sem.available_permits() + 1))
65
+ }
66
+ }
67
+
68
+ /// Wraps an [OwnedSemaphorePermit] to update metrics when it's dropped
69
+ pub(crate) struct OwnedMeteredSemPermit {
70
+ inner: OwnedSemaphorePermit,
71
+ record_fn: Box<dyn Fn() + Send + Sync>,
72
+ }
73
+ impl Drop for OwnedMeteredSemPermit {
74
+ fn drop(&mut self) {
75
+ (self.record_fn)()
76
+ }
77
+ }
78
+ impl Debug for OwnedMeteredSemPermit {
79
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80
+ self.inner.fmt(f)
81
+ }
82
+ }
83
+
84
+ /// From the input stream, create a new stream which only pulls from the input stream when allowed.
85
+ /// When allowed is determined by the passed in `proceeder` which must return a future every time
86
+ /// it's called. The input stream is only pulled from when that future resolves.
87
+ pub(crate) fn stream_when_allowed<S, F, FF>(
88
+ input: S,
89
+ proceeder: FF,
90
+ ) -> impl Stream<Item = (S::Item, F::Output)>
91
+ where
92
+ S: Stream + Send + 'static,
93
+ F: Future,
94
+ FF: FnMut() -> F,
95
+ {
96
+ let acceptable_notify = Arc::new(Notify::new());
97
+ acceptable_notify.notify_one();
98
+ let stream = stream::unfold(
99
+ (proceeder, input.boxed()),
100
+ |(mut proceeder, mut input)| async {
101
+ let v = proceeder().await;
102
+ input.next().await.map(|i| ((i, v), (proceeder, input)))
103
+ },
104
+ );
105
+ stream
106
+ }
107
+
108
+ macro_rules! dbg_panic {
109
+ ($($arg:tt)*) => {
110
+ error!($($arg)*);
111
+ debug_assert!(true, $($arg)*);
112
+ };
113
+ }
114
+ pub(crate) use dbg_panic;
115
+
116
+ #[cfg(test)]
117
+ mod tests {
118
+ use super::*;
119
+ use futures::pin_mut;
120
+ use std::{cell::RefCell, task::Poll};
121
+ use tokio::sync::mpsc::unbounded_channel;
122
+
123
+ // This is fine. Test only / guaranteed to happen serially.
124
+ #[allow(clippy::await_holding_refcell_ref)]
125
+ #[test]
126
+ fn stream_when_allowed_works() {
127
+ let inputs = stream::iter([1, 2, 3]);
128
+ let (allow_tx, allow_rx) = unbounded_channel();
129
+ let allow_rx = RefCell::new(allow_rx);
130
+ let when_allowed = stream_when_allowed(inputs, || async {
131
+ allow_rx.borrow_mut().recv().await.unwrap()
132
+ });
133
+
134
+ let waker = futures::task::noop_waker_ref();
135
+ let mut cx = std::task::Context::from_waker(waker);
136
+ pin_mut!(when_allowed);
137
+
138
+ allow_tx.send(()).unwrap();
139
+ assert_eq!(
140
+ when_allowed.poll_next_unpin(&mut cx),
141
+ Poll::Ready(Some((1, ())))
142
+ );
143
+ // Now, it won't be ready
144
+ for _ in 1..10 {
145
+ assert_eq!(when_allowed.poll_next_unpin(&mut cx), Poll::Pending);
146
+ }
147
+ allow_tx.send(()).unwrap();
148
+ assert_eq!(
149
+ when_allowed.poll_next_unpin(&mut cx),
150
+ Poll::Ready(Some((2, ())))
151
+ );
152
+ for _ in 1..10 {
153
+ assert_eq!(when_allowed.poll_next_unpin(&mut cx), Poll::Pending);
154
+ }
155
+ allow_tx.send(()).unwrap();
156
+ assert_eq!(
157
+ when_allowed.poll_next_unpin(&mut cx),
158
+ Poll::Ready(Some((3, ())))
159
+ );
160
+ for _ in 1..10 {
161
+ assert_eq!(when_allowed.poll_next_unpin(&mut cx), Poll::Pending);
162
+ }
163
+ allow_tx.send(()).unwrap();
164
+ assert_eq!(when_allowed.poll_next_unpin(&mut cx), Poll::Ready(None));
165
+ }
166
+ }