temporalio 0.0.2 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (320) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -23
  3. data/bridge/Cargo.lock +185 -76
  4. data/bridge/Cargo.toml +6 -4
  5. data/bridge/sdk-core/README.md +19 -6
  6. data/bridge/sdk-core/client/src/lib.rs +215 -39
  7. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  8. data/bridge/sdk-core/client/src/raw.rs +4 -4
  9. data/bridge/sdk-core/client/src/retry.rs +32 -20
  10. data/bridge/sdk-core/core/Cargo.toml +22 -9
  11. data/bridge/sdk-core/core/src/abstractions.rs +203 -14
  12. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +76 -41
  13. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  14. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +204 -83
  15. data/bridge/sdk-core/core/src/core_tests/queries.rs +3 -4
  16. data/bridge/sdk-core/core/src/core_tests/workers.rs +1 -3
  17. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +397 -54
  18. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  19. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  20. data/bridge/sdk-core/core/src/lib.rs +16 -9
  21. data/bridge/sdk-core/core/src/telemetry/log_export.rs +1 -1
  22. data/bridge/sdk-core/core/src/telemetry/metrics.rs +69 -35
  23. data/bridge/sdk-core/core/src/telemetry/mod.rs +29 -13
  24. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +17 -12
  25. data/bridge/sdk-core/core/src/test_help/mod.rs +62 -12
  26. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  27. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +352 -122
  29. data/bridge/sdk-core/core/src/worker/activities.rs +233 -157
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +22 -2
  31. data/bridge/sdk-core/core/src/worker/client.rs +18 -2
  32. data/bridge/sdk-core/core/src/worker/mod.rs +165 -58
  33. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  34. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  35. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +856 -277
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +100 -43
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +7 -7
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +5 -4
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +87 -27
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +5 -4
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +5 -4
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +5 -4
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +137 -62
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +25 -17
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +7 -6
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +103 -152
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +7 -7
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -7
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +5 -16
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +201 -121
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +11 -14
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +30 -15
  55. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1026 -376
  56. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +460 -384
  57. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  58. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  59. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  60. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +448 -718
  63. data/bridge/sdk-core/core-api/Cargo.toml +2 -1
  64. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  65. data/bridge/sdk-core/core-api/src/lib.rs +6 -2
  66. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -6
  67. data/bridge/sdk-core/core-api/src/worker.rs +14 -1
  68. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  69. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  70. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  71. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  85. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  86. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  87. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  88. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  89. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  90. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  91. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +7 -0
  92. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +1 -0
  93. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  94. data/bridge/sdk-core/sdk/Cargo.toml +3 -2
  95. data/bridge/sdk-core/sdk/src/lib.rs +87 -20
  96. data/bridge/sdk-core/sdk/src/workflow_future.rs +9 -8
  97. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  98. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -1
  99. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +100 -87
  100. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +5 -1
  101. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +175 -57
  102. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  103. data/bridge/sdk-core/test-utils/Cargo.toml +3 -1
  104. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  105. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  106. data/bridge/sdk-core/test-utils/src/lib.rs +82 -23
  107. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  108. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  109. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  110. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  111. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  112. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
  113. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
  114. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
  115. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  116. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  117. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  118. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  119. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  120. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  121. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  122. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +72 -191
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  127. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  128. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  129. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  130. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  131. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  132. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +10 -11
  133. data/bridge/sdk-core/tests/main.rs +3 -13
  134. data/bridge/sdk-core/tests/runner.rs +75 -36
  135. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  136. data/bridge/src/connection.rs +41 -25
  137. data/bridge/src/lib.rs +269 -14
  138. data/bridge/src/runtime.rs +1 -1
  139. data/bridge/src/test_server.rs +153 -0
  140. data/bridge/src/worker.rs +89 -16
  141. data/lib/gen/temporal/api/command/v1/message_pb.rb +4 -18
  142. data/lib/gen/temporal/api/common/v1/message_pb.rb +4 -0
  143. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +1 -3
  144. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -3
  145. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +2 -0
  146. data/lib/gen/temporal/api/enums/v1/update_pb.rb +6 -4
  147. data/lib/gen/temporal/api/history/v1/message_pb.rb +27 -19
  148. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -0
  149. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +3 -0
  150. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  151. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  152. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  153. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  154. data/lib/gen/temporal/api/update/v1/message_pb.rb +72 -0
  155. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +26 -16
  156. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  157. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  158. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  159. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  160. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  161. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  162. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +27 -21
  163. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +28 -24
  164. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  165. data/lib/temporalio/activity/context.rb +13 -8
  166. data/lib/temporalio/activity/info.rb +1 -1
  167. data/lib/temporalio/bridge/connect_options.rb +15 -0
  168. data/lib/temporalio/bridge/retry_config.rb +24 -0
  169. data/lib/temporalio/bridge/tls_options.rb +19 -0
  170. data/lib/temporalio/bridge.rb +1 -1
  171. data/lib/temporalio/client/implementation.rb +8 -8
  172. data/lib/temporalio/connection/retry_config.rb +44 -0
  173. data/lib/temporalio/connection/service.rb +20 -0
  174. data/lib/temporalio/connection/test_service.rb +92 -0
  175. data/lib/temporalio/connection/tls_options.rb +51 -0
  176. data/lib/temporalio/connection/workflow_service.rb +731 -0
  177. data/lib/temporalio/connection.rb +55 -720
  178. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  179. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  180. data/lib/temporalio/interceptor/chain.rb +5 -5
  181. data/lib/temporalio/interceptor/client.rb +8 -4
  182. data/lib/temporalio/interceptor.rb +22 -0
  183. data/lib/temporalio/retry_policy.rb +13 -3
  184. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  185. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  186. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  187. data/lib/temporalio/testing.rb +175 -0
  188. data/lib/temporalio/version.rb +1 -1
  189. data/lib/temporalio/worker/activity_runner.rb +26 -4
  190. data/lib/temporalio/worker/activity_worker.rb +44 -18
  191. data/lib/temporalio/worker/sync_worker.rb +47 -11
  192. data/lib/temporalio/worker.rb +27 -21
  193. data/lib/temporalio/workflow/async.rb +46 -0
  194. data/lib/temporalio/workflow/future.rb +138 -0
  195. data/lib/temporalio/workflow/info.rb +76 -0
  196. data/lib/thermite_patch.rb +10 -0
  197. data/sig/async.rbs +17 -0
  198. data/sig/protobuf.rbs +16 -0
  199. data/sig/protos/dependencies/gogoproto/gogo.rbs +914 -0
  200. data/sig/protos/google/protobuf/any.rbs +157 -0
  201. data/sig/protos/google/protobuf/descriptor.rbs +2825 -0
  202. data/sig/protos/google/protobuf/duration.rbs +114 -0
  203. data/sig/protos/google/protobuf/empty.rbs +36 -0
  204. data/sig/protos/google/protobuf/timestamp.rbs +145 -0
  205. data/sig/protos/google/protobuf/wrappers.rbs +358 -0
  206. data/sig/protos/temporal/api/batch/v1/message.rbs +300 -0
  207. data/sig/protos/temporal/api/command/v1/message.rbs +1399 -0
  208. data/sig/protos/temporal/api/common/v1/message.rbs +528 -0
  209. data/sig/protos/temporal/api/enums/v1/batch_operation.rbs +79 -0
  210. data/sig/protos/temporal/api/enums/v1/command_type.rbs +68 -0
  211. data/sig/protos/temporal/api/enums/v1/common.rbs +118 -0
  212. data/sig/protos/temporal/api/enums/v1/event_type.rbs +264 -0
  213. data/sig/protos/temporal/api/enums/v1/failed_cause.rbs +277 -0
  214. data/sig/protos/temporal/api/enums/v1/namespace.rbs +108 -0
  215. data/sig/protos/temporal/api/enums/v1/query.rbs +81 -0
  216. data/sig/protos/temporal/api/enums/v1/reset.rbs +44 -0
  217. data/sig/protos/temporal/api/enums/v1/schedule.rbs +72 -0
  218. data/sig/protos/temporal/api/enums/v1/task_queue.rbs +92 -0
  219. data/sig/protos/temporal/api/enums/v1/update.rbs +64 -0
  220. data/sig/protos/temporal/api/enums/v1/workflow.rbs +371 -0
  221. data/sig/protos/temporal/api/errordetails/v1/message.rbs +551 -0
  222. data/sig/protos/temporal/api/failure/v1/message.rbs +581 -0
  223. data/sig/protos/temporal/api/filter/v1/message.rbs +171 -0
  224. data/sig/protos/temporal/api/history/v1/message.rbs +4609 -0
  225. data/sig/protos/temporal/api/namespace/v1/message.rbs +410 -0
  226. data/sig/protos/temporal/api/operatorservice/v1/request_response.rbs +643 -0
  227. data/sig/protos/temporal/api/operatorservice/v1/service.rbs +17 -0
  228. data/sig/protos/temporal/api/protocol/v1/message.rbs +84 -0
  229. data/sig/protos/temporal/api/query/v1/message.rbs +182 -0
  230. data/sig/protos/temporal/api/replication/v1/message.rbs +148 -0
  231. data/sig/protos/temporal/api/schedule/v1/message.rbs +1488 -0
  232. data/sig/protos/temporal/api/sdk/v1/task_complete_metadata.rbs +110 -0
  233. data/sig/protos/temporal/api/taskqueue/v1/message.rbs +486 -0
  234. data/sig/protos/temporal/api/testservice/v1/request_response.rbs +249 -0
  235. data/sig/protos/temporal/api/testservice/v1/service.rbs +15 -0
  236. data/sig/protos/temporal/api/update/v1/message.rbs +489 -0
  237. data/sig/protos/temporal/api/version/v1/message.rbs +184 -0
  238. data/sig/protos/temporal/api/workflow/v1/message.rbs +824 -0
  239. data/sig/protos/temporal/api/workflowservice/v1/request_response.rbs +7250 -0
  240. data/sig/protos/temporal/api/workflowservice/v1/service.rbs +22 -0
  241. data/sig/protos/temporal/sdk/core/activity_result/activity_result.rbs +380 -0
  242. data/sig/protos/temporal/sdk/core/activity_task/activity_task.rbs +386 -0
  243. data/sig/protos/temporal/sdk/core/child_workflow/child_workflow.rbs +323 -0
  244. data/sig/protos/temporal/sdk/core/common/common.rbs +62 -0
  245. data/sig/protos/temporal/sdk/core/core_interface.rbs +101 -0
  246. data/sig/protos/temporal/sdk/core/external_data/external_data.rbs +119 -0
  247. data/sig/protos/temporal/sdk/core/workflow_activation/workflow_activation.rbs +1473 -0
  248. data/sig/protos/temporal/sdk/core/workflow_commands/workflow_commands.rbs +1784 -0
  249. data/sig/protos/temporal/sdk/core/workflow_completion/workflow_completion.rbs +180 -0
  250. data/sig/ruby.rbs +12 -0
  251. data/sig/temporalio/activity/context.rbs +29 -0
  252. data/sig/temporalio/activity/info.rbs +43 -0
  253. data/sig/temporalio/activity.rbs +19 -0
  254. data/sig/temporalio/bridge/connect_options.rbs +19 -0
  255. data/sig/temporalio/bridge/error.rbs +8 -0
  256. data/sig/temporalio/bridge/retry_config.rbs +21 -0
  257. data/sig/temporalio/bridge/tls_options.rbs +17 -0
  258. data/sig/temporalio/bridge.rbs +71 -0
  259. data/sig/temporalio/client/implementation.rbs +38 -0
  260. data/sig/temporalio/client/workflow_handle.rbs +41 -0
  261. data/sig/temporalio/client.rbs +35 -0
  262. data/sig/temporalio/connection/retry_config.rbs +37 -0
  263. data/sig/temporalio/connection/service.rbs +14 -0
  264. data/sig/temporalio/connection/test_service.rbs +13 -0
  265. data/sig/temporalio/connection/tls_options.rbs +43 -0
  266. data/sig/temporalio/connection/workflow_service.rbs +48 -0
  267. data/sig/temporalio/connection.rbs +30 -0
  268. data/sig/temporalio/data_converter.rbs +35 -0
  269. data/sig/temporalio/error/failure.rbs +121 -0
  270. data/sig/temporalio/error/workflow_failure.rbs +9 -0
  271. data/sig/temporalio/errors.rbs +36 -0
  272. data/sig/temporalio/failure_converter/base.rbs +12 -0
  273. data/sig/temporalio/failure_converter/basic.rbs +86 -0
  274. data/sig/temporalio/failure_converter.rbs +5 -0
  275. data/sig/temporalio/interceptor/activity_inbound.rbs +21 -0
  276. data/sig/temporalio/interceptor/activity_outbound.rbs +10 -0
  277. data/sig/temporalio/interceptor/chain.rbs +24 -0
  278. data/sig/temporalio/interceptor/client.rbs +148 -0
  279. data/sig/temporalio/interceptor.rbs +6 -0
  280. data/sig/temporalio/payload_codec/base.rbs +12 -0
  281. data/sig/temporalio/payload_converter/base.rbs +12 -0
  282. data/sig/temporalio/payload_converter/bytes.rbs +9 -0
  283. data/sig/temporalio/payload_converter/composite.rbs +19 -0
  284. data/sig/temporalio/payload_converter/encoding_base.rbs +14 -0
  285. data/sig/temporalio/payload_converter/json.rbs +9 -0
  286. data/sig/temporalio/payload_converter/nil.rbs +9 -0
  287. data/sig/temporalio/payload_converter.rbs +5 -0
  288. data/sig/temporalio/retry_policy.rbs +25 -0
  289. data/sig/temporalio/retry_state.rbs +20 -0
  290. data/sig/temporalio/runtime.rbs +12 -0
  291. data/sig/temporalio/testing/time_skipping_handle.rbs +15 -0
  292. data/sig/temporalio/testing/time_skipping_interceptor.rbs +13 -0
  293. data/sig/temporalio/testing/workflow_environment.rbs +22 -0
  294. data/sig/temporalio/testing.rbs +35 -0
  295. data/sig/temporalio/timeout_type.rbs +15 -0
  296. data/sig/temporalio/version.rbs +3 -0
  297. data/sig/temporalio/worker/activity_runner.rbs +35 -0
  298. data/sig/temporalio/worker/activity_worker.rbs +44 -0
  299. data/sig/temporalio/worker/reactor.rbs +22 -0
  300. data/sig/temporalio/worker/runner.rbs +21 -0
  301. data/sig/temporalio/worker/sync_worker.rbs +23 -0
  302. data/sig/temporalio/worker/thread_pool_executor.rbs +23 -0
  303. data/sig/temporalio/worker.rbs +46 -0
  304. data/sig/temporalio/workflow/async.rbs +9 -0
  305. data/sig/temporalio/workflow/execution_info.rbs +55 -0
  306. data/sig/temporalio/workflow/execution_status.rbs +21 -0
  307. data/sig/temporalio/workflow/future.rbs +40 -0
  308. data/sig/temporalio/workflow/id_reuse_policy.rbs +15 -0
  309. data/sig/temporalio/workflow/info.rbs +55 -0
  310. data/sig/temporalio/workflow/query_reject_condition.rbs +14 -0
  311. data/sig/temporalio.rbs +2 -0
  312. data/sig/thermite_patch.rbs +15 -0
  313. data/temporalio.gemspec +6 -4
  314. metadata +183 -17
  315. data/bridge/sdk-core/Cargo.lock +0 -2606
  316. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
  317. data/lib/bridge.so +0 -0
  318. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +0 -25
  319. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +0 -49
  320. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
@@ -23,6 +23,9 @@ use std::os::unix::fs::OpenOptionsExt;
23
23
  use std::process::Stdio;
24
24
 
25
25
  /// Configuration for Temporalite.
26
+ /// Will be removed eventually as its successor, Temporal CLI matures.
27
+ /// We don't care for the duplication between this struct and [TemporalDevServerConfig] and prefer that over another
28
+ /// abstraction since the existence of this struct is temporary.
26
29
  #[derive(Debug, Clone, derive_builder::Builder)]
27
30
  pub struct TemporaliteConfig {
28
31
  /// Required path to executable or download info.
@@ -59,7 +62,10 @@ impl TemporaliteConfig {
59
62
  /// Start a Temporalite server with configurable stdout destination.
60
63
  pub async fn start_server_with_output(&self, output: Stdio) -> anyhow::Result<EphemeralServer> {
61
64
  // Get exe path
62
- let exe_path = self.exe.get_or_download("temporalite").await?;
65
+ let exe_path = self
66
+ .exe
67
+ .get_or_download("temporalite", "temporalite")
68
+ .await?;
63
69
 
64
70
  // Get free port if not already given
65
71
  let port = self.port.unwrap_or_else(|| get_free_port(&self.ip));
@@ -77,6 +83,8 @@ impl TemporaliteConfig {
77
83
  self.log.0.clone(),
78
84
  "--log-level".to_owned(),
79
85
  self.log.1.clone(),
86
+ "--dynamic-config-value".to_owned(),
87
+ "frontend.enableServerVersionCheck=false".to_owned(),
80
88
  ];
81
89
  if let Some(db_filename) = &self.db_filename {
82
90
  args.push("--filename".to_owned());
@@ -101,6 +109,86 @@ impl TemporaliteConfig {
101
109
  }
102
110
  }
103
111
 
112
+ /// Configuration for Temporal CLI dev server.
113
+ #[derive(Debug, Clone, derive_builder::Builder)]
114
+ pub struct TemporalDevServerConfig {
115
+ /// Required path to executable or download info.
116
+ pub exe: EphemeralExe,
117
+ /// Namespace to use.
118
+ #[builder(default = "\"default\".to_owned()")]
119
+ pub namespace: String,
120
+ /// IP to bind to.
121
+ #[builder(default = "\"127.0.0.1\".to_owned()")]
122
+ pub ip: String,
123
+ /// Port to use or obtains a free one if none given.
124
+ #[builder(default)]
125
+ pub port: Option<u16>,
126
+ /// Sqlite DB filename if persisting or non-persistent if none.
127
+ #[builder(default)]
128
+ pub db_filename: Option<String>,
129
+ /// Whether to enable the UI.
130
+ #[builder(default)]
131
+ pub ui: bool,
132
+ /// Log format and level
133
+ #[builder(default = "(\"pretty\".to_owned(), \"warn\".to_owned())")]
134
+ pub log: (String, String),
135
+ /// Additional arguments to Temporalite.
136
+ #[builder(default)]
137
+ pub extra_args: Vec<String>,
138
+ }
139
+
140
+ impl TemporalDevServerConfig {
141
+ /// Start a Temporal CLI dev server.
142
+ pub async fn start_server(&self) -> anyhow::Result<EphemeralServer> {
143
+ self.start_server_with_output(Stdio::inherit()).await
144
+ }
145
+
146
+ /// Start a Temporal CLI dev server with configurable stdout destination.
147
+ pub async fn start_server_with_output(&self, output: Stdio) -> anyhow::Result<EphemeralServer> {
148
+ // Get exe path
149
+ let exe_path = self.exe.get_or_download("cli", "temporal").await?;
150
+
151
+ // Get free port if not already given
152
+ let port = self.port.unwrap_or_else(|| get_free_port(&self.ip));
153
+
154
+ // Build arg set
155
+ let mut args = vec![
156
+ "server".to_owned(),
157
+ "start-dev".to_owned(),
158
+ "--port".to_owned(),
159
+ port.to_string(),
160
+ "--namespace".to_owned(),
161
+ self.namespace.clone(),
162
+ "--ip".to_owned(),
163
+ self.ip.clone(),
164
+ "--log-format".to_owned(),
165
+ self.log.0.clone(),
166
+ "--log-level".to_owned(),
167
+ self.log.1.clone(),
168
+ "--dynamic-config-value".to_owned(),
169
+ "frontend.enableServerVersionCheck=false".to_owned(),
170
+ ];
171
+ if let Some(db_filename) = &self.db_filename {
172
+ args.push("--filename".to_owned());
173
+ args.push(db_filename.clone());
174
+ }
175
+ if !self.ui {
176
+ args.push("--headless".to_owned());
177
+ }
178
+ args.extend(self.extra_args.clone());
179
+
180
+ // Start
181
+ EphemeralServer::start(EphemeralServerConfig {
182
+ exe_path,
183
+ port,
184
+ args,
185
+ has_test_service: false,
186
+ output,
187
+ })
188
+ .await
189
+ }
190
+ }
191
+
104
192
  /// Configuration for the test server.
105
193
  #[derive(Debug, Clone, derive_builder::Builder)]
106
194
  pub struct TestServerConfig {
@@ -123,7 +211,10 @@ impl TestServerConfig {
123
211
  /// Start a test server with configurable stdout.
124
212
  pub async fn start_server_with_output(&self, output: Stdio) -> anyhow::Result<EphemeralServer> {
125
213
  // Get exe path
126
- let exe_path = self.exe.get_or_download("temporal-test-server").await?;
214
+ let exe_path = self
215
+ .exe
216
+ .get_or_download("temporal-test-server", "temporal-test-server")
217
+ .await?;
127
218
 
128
219
  // Get free port if not already given
129
220
  let port = self.port.unwrap_or_else(|| get_free_port("0.0.0.0"));
@@ -172,7 +263,7 @@ impl EphemeralServer {
172
263
  .stdout(config.output)
173
264
  .spawn()?;
174
265
  let target = format!("127.0.0.1:{}", config.port);
175
- let target_url = format!("http://{}", target);
266
+ let target_url = format!("http://{target}");
176
267
  let success = Ok(EphemeralServer {
177
268
  target,
178
269
  has_test_service: config.has_test_service,
@@ -262,7 +353,7 @@ pub enum EphemeralExe {
262
353
  #[derive(Debug, Clone)]
263
354
  pub enum EphemeralExeVersion {
264
355
  /// Use a default version for the given SDK name and version.
265
- Default {
356
+ SDKDefault {
266
357
  /// Name of the SDK to get the default for.
267
358
  sdk_name: String,
268
359
  /// Version of the SDK to get the default for.
@@ -280,7 +371,11 @@ struct DownloadInfo {
280
371
  }
281
372
 
282
373
  impl EphemeralExe {
283
- async fn get_or_download(&self, artifact_name: &str) -> anyhow::Result<PathBuf> {
374
+ async fn get_or_download(
375
+ &self,
376
+ artifact_name: &str,
377
+ downloaded_name_prefix: &str,
378
+ ) -> anyhow::Result<PathBuf> {
284
379
  match self {
285
380
  EphemeralExe::ExistingPath(exe_path) => {
286
381
  let path = PathBuf::from(exe_path);
@@ -301,12 +396,12 @@ impl EphemeralExe {
301
396
  };
302
397
  // Create dest file based on SDK name/version or fixed version
303
398
  let dest = dest_dir.join(match version {
304
- EphemeralExeVersion::Default {
399
+ EphemeralExeVersion::SDKDefault {
305
400
  sdk_name,
306
401
  sdk_version,
307
- } => format!("{}-{}-{}{}", artifact_name, sdk_name, sdk_version, out_ext),
402
+ } => format!("{downloaded_name_prefix}-{sdk_name}-{sdk_version}{out_ext}"),
308
403
  EphemeralExeVersion::Fixed(version) => {
309
- format!("{}-{}{}", artifact_name, version, out_ext)
404
+ format!("{downloaded_name_prefix}-{version}{out_ext}")
310
405
  }
311
406
  });
312
407
  debug!(
@@ -327,7 +422,7 @@ impl EphemeralExe {
327
422
  };
328
423
  let mut get_info_params = vec![("arch", arch), ("platform", platform)];
329
424
  let version_name = match version {
330
- EphemeralExeVersion::Default {
425
+ EphemeralExeVersion::SDKDefault {
331
426
  sdk_name,
332
427
  sdk_version,
333
428
  } => {
@@ -340,8 +435,7 @@ impl EphemeralExe {
340
435
  let client = reqwest::Client::new();
341
436
  let info: DownloadInfo = client
342
437
  .get(format!(
343
- "https://temporal.download/{}/{}",
344
- artifact_name, version_name
438
+ "https://temporal.download/{artifact_name}/{version_name}"
345
439
  ))
346
440
  .query(&get_info_params)
347
441
  .send()
@@ -371,7 +465,7 @@ impl EphemeralExe {
371
465
  fn get_free_port(bind_ip: &str) -> u16 {
372
466
  // Can just ask OS to give us a port then close socket. OS's don't give that
373
467
  // port back to anyone else anytime soon.
374
- std::net::TcpListener::bind(format!("{}:0", bind_ip))
468
+ std::net::TcpListener::bind(format!("{bind_ip}:0"))
375
469
  .unwrap()
376
470
  .local_addr()
377
471
  .unwrap()
@@ -0,0 +1,136 @@
1
+ //! Utilities for and tracking of internal versions which alter history in incompatible ways
2
+ //! so that we can use older code paths for workflows executed on older core versions.
3
+
4
+ use std::collections::{BTreeSet, HashSet};
5
+ use temporal_sdk_core_protos::temporal::api::{
6
+ history::v1::WorkflowTaskCompletedEventAttributes, sdk::v1::WorkflowTaskCompletedMetadata,
7
+ workflowservice::v1::get_system_info_response,
8
+ };
9
+
10
+ /// This enumeration contains internal flags that may result in incompatible history changes with
11
+ /// older workflows, or other breaking changes.
12
+ ///
13
+ /// When a flag has existed long enough the version it was introduced in is no longer supported, it
14
+ /// may be removed from the enum. *Importantly*, all variants must be given explicit values, such
15
+ /// that removing older variants does not create any change in existing values. Removed flag
16
+ /// variants must be reserved forever (a-la protobuf), and should be called out in a comment.
17
+ #[repr(u32)]
18
+ #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Debug)]
19
+ pub(crate) enum CoreInternalFlags {
20
+ /// In this flag, additional checks were added to a number of state machines to ensure that
21
+ /// the ID and type of activities, local activities, and child workflows match during replay.
22
+ IdAndTypeDeterminismChecks = 1,
23
+ /// We received a value higher than this code can understand.
24
+ TooHigh = u32::MAX,
25
+ }
26
+
27
+ #[derive(Debug, Clone, PartialEq, Eq)]
28
+ pub(crate) struct InternalFlags {
29
+ enabled: bool,
30
+ core: BTreeSet<CoreInternalFlags>,
31
+ lang: BTreeSet<u32>,
32
+ core_since_last_complete: HashSet<CoreInternalFlags>,
33
+ lang_since_last_complete: HashSet<u32>,
34
+ }
35
+
36
+ impl InternalFlags {
37
+ pub fn new(server_capabilities: &get_system_info_response::Capabilities) -> Self {
38
+ Self {
39
+ enabled: server_capabilities.sdk_metadata,
40
+ core: Default::default(),
41
+ lang: Default::default(),
42
+ core_since_last_complete: Default::default(),
43
+ lang_since_last_complete: Default::default(),
44
+ }
45
+ }
46
+
47
+ pub fn add_from_complete(&mut self, e: &WorkflowTaskCompletedEventAttributes) {
48
+ if !self.enabled {
49
+ return;
50
+ }
51
+
52
+ if let Some(metadata) = e.sdk_metadata.as_ref() {
53
+ self.core.extend(
54
+ metadata
55
+ .core_used_flags
56
+ .iter()
57
+ .map(|u| CoreInternalFlags::from_u32(*u)),
58
+ );
59
+ self.lang.extend(metadata.lang_used_flags.iter());
60
+ }
61
+ }
62
+
63
+ pub fn add_lang_used(&mut self, flags: impl IntoIterator<Item = u32>) {
64
+ if !self.enabled {
65
+ return;
66
+ }
67
+
68
+ self.lang_since_last_complete.extend(flags.into_iter());
69
+ }
70
+
71
+ /// Returns true if this flag may currently be used. If `should_record` is true, always returns
72
+ /// true and records the flag as being used, for taking later via
73
+ /// [Self::gather_for_wft_complete].
74
+ pub fn try_use(&mut self, core_patch: CoreInternalFlags, should_record: bool) -> bool {
75
+ if !self.enabled {
76
+ // If the server does not support the metadata field, we must assume
77
+ return false;
78
+ }
79
+
80
+ if should_record {
81
+ self.core_since_last_complete.insert(core_patch);
82
+ true
83
+ } else {
84
+ self.core.contains(&core_patch)
85
+ }
86
+ }
87
+
88
+ /// Wipes the recorded flags used during the current WFT and returns a partially filled
89
+ /// sdk metadata message that can be combined with any existing data before sending the WFT
90
+ /// complete
91
+ pub fn gather_for_wft_complete(&mut self) -> WorkflowTaskCompletedMetadata {
92
+ WorkflowTaskCompletedMetadata {
93
+ core_used_flags: self
94
+ .core_since_last_complete
95
+ .drain()
96
+ .map(|p| p as u32)
97
+ .collect(),
98
+ lang_used_flags: self.lang_since_last_complete.drain().collect(),
99
+ }
100
+ }
101
+
102
+ pub fn all_lang(&self) -> &BTreeSet<u32> {
103
+ &self.lang
104
+ }
105
+ }
106
+
107
+ impl CoreInternalFlags {
108
+ fn from_u32(v: u32) -> Self {
109
+ match v {
110
+ 1 => Self::IdAndTypeDeterminismChecks,
111
+ _ => Self::TooHigh,
112
+ }
113
+ }
114
+ }
115
+
116
+ #[cfg(test)]
117
+ mod tests {
118
+ use super::*;
119
+ use temporal_sdk_core_protos::temporal::api::workflowservice::v1::get_system_info_response::Capabilities;
120
+
121
+ #[test]
122
+ fn disabled_in_capabilities_disables() {
123
+ let mut f = InternalFlags::new(&Capabilities::default());
124
+ f.add_lang_used([1]);
125
+ f.add_from_complete(&WorkflowTaskCompletedEventAttributes {
126
+ sdk_metadata: Some(WorkflowTaskCompletedMetadata {
127
+ core_used_flags: vec![1],
128
+ lang_used_flags: vec![],
129
+ }),
130
+ ..Default::default()
131
+ });
132
+ let gathered = f.gather_for_wft_complete();
133
+ assert_matches!(gathered.core_used_flags.as_slice(), &[]);
134
+ assert_matches!(gathered.lang_used_flags.as_slice(), &[]);
135
+ }
136
+ }
@@ -13,6 +13,7 @@ extern crate core;
13
13
 
14
14
  mod abstractions;
15
15
  pub mod ephemeral_server;
16
+ mod internal_flags;
16
17
  mod pollers;
17
18
  mod protosext;
18
19
  pub mod replay;
@@ -36,13 +37,16 @@ pub use temporal_sdk_core_api as api;
36
37
  pub use temporal_sdk_core_protos as protos;
37
38
  pub use temporal_sdk_core_protos::TaskToken;
38
39
  pub use url::Url;
40
+ #[cfg(feature = "save_wf_inputs")]
41
+ pub use worker::replay_wf_state_inputs;
39
42
  pub use worker::{Worker, WorkerConfig, WorkerConfigBuilder};
40
43
 
41
44
  use crate::{
42
45
  replay::{mock_client_from_histories, Historator, HistoryForReplay},
43
46
  telemetry::{
44
- metrics::MetricsContext, remove_trace_subscriber_for_current_thread,
45
- set_trace_subscriber_for_current_thread, telemetry_init, TelemetryInstance,
47
+ metrics::{MetricsContext, TemporalMeter},
48
+ remove_trace_subscriber_for_current_thread, set_trace_subscriber_for_current_thread,
49
+ telemetry_init, TelemetryInstance,
46
50
  },
47
51
  worker::client::WorkerClientBag,
48
52
  };
@@ -51,7 +55,7 @@ use std::sync::Arc;
51
55
  use temporal_client::{ConfiguredClient, TemporalServiceClientWithMetrics};
52
56
  use temporal_sdk_core_api::{
53
57
  errors::{CompleteActivityError, PollActivityError, PollWfError},
54
- telemetry::{CoreTelemetry, TelemetryOptions},
58
+ telemetry::TelemetryOptions,
55
59
  Worker as WorkerTrait,
56
60
  };
57
61
  use temporal_sdk_core_protos::coresdk::ActivityHeartbeat;
@@ -62,7 +66,7 @@ use temporal_sdk_core_protos::coresdk::ActivityHeartbeat;
62
66
  /// After the worker is initialized, you should use [CoreRuntime::tokio_handle] to run the worker's
63
67
  /// async functions.
64
68
  ///
65
- /// Lang implementations may pass in a [temporal_client::ConfiguredClient] directly (or a
69
+ /// Lang implementations may pass in a [ConfiguredClient] directly (or a
66
70
  /// [RetryClient] wrapping one, or a handful of other variants of the same idea). When they do so,
67
71
  /// this function will always overwrite the client retry configuration, force the client to use the
68
72
  /// namespace defined in the worker config, and set the client identity appropriately. IE: Use
@@ -97,9 +101,12 @@ where
97
101
  worker_config.use_worker_versioning,
98
102
  ));
99
103
 
100
- let metrics = MetricsContext::top_level(worker_config.namespace.clone(), &runtime.telemetry)
101
- .with_task_q(worker_config.task_queue.clone());
102
- Ok(Worker::new(worker_config, sticky_q, client_bag, metrics))
104
+ Ok(Worker::new(
105
+ worker_config,
106
+ sticky_q,
107
+ client_bag,
108
+ Some(&runtime.telemetry),
109
+ ))
103
110
  }
104
111
 
105
112
  /// Create a worker for replaying a specific history. It will auto-shutdown as soon as the history
@@ -126,7 +133,7 @@ where
126
133
  let post_activate = historator.get_post_activate_hook();
127
134
  let shutdown_tok = historator.get_shutdown_setter();
128
135
  let client = mock_client_from_histories(historator);
129
- let mut worker = Worker::new(config, None, Arc::new(client), MetricsContext::no_op());
136
+ let mut worker = Worker::new(config, None, Arc::new(client), None);
130
137
  worker.set_post_activate_hook(post_activate);
131
138
  shutdown_tok(worker.shutdown_token());
132
139
  Ok(worker)
@@ -258,7 +265,7 @@ impl CoreRuntime {
258
265
  }
259
266
 
260
267
  /// Returns the metric meter used for recording metrics, if they were enabled.
261
- pub fn metric_meter(&self) -> Option<&opentelemetry::metrics::Meter> {
268
+ pub fn metric_meter(&self) -> Option<TemporalMeter> {
262
269
  self.telemetry.get_metric_meter()
263
270
  }
264
271
 
@@ -139,7 +139,7 @@ impl<'a> tracing::field::Visit for JsonVisitor<'a> {
139
139
  fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
140
140
  self.0.insert(
141
141
  field.name().to_string(),
142
- serde_json::json!(format!("{:?}", value)),
142
+ serde_json::json!(format!("{value:?}")),
143
143
  );
144
144
  }
145
145
  }
@@ -10,8 +10,8 @@ use opentelemetry::{
10
10
  },
11
11
  Context, KeyValue,
12
12
  };
13
- use std::{sync::Arc, time::Duration};
14
- use temporal_sdk_core_api::telemetry::CoreTelemetry;
13
+ use std::{ops::Deref, sync::Arc, time::Duration};
14
+ use temporal_client::ClientMetricProvider;
15
15
 
16
16
  /// Used to track context associated with metrics, and record/update them
17
17
  ///
@@ -24,6 +24,46 @@ pub(crate) struct MetricsContext {
24
24
  instruments: Arc<Instruments>,
25
25
  }
26
26
 
27
+ /// Wraps OTel's [Meter] to ensure we name our metrics properly, or any other temporal-specific
28
+ /// metrics customizations
29
+ #[derive(derive_more::Constructor)]
30
+ pub struct TemporalMeter<'a> {
31
+ inner: &'a Meter,
32
+ metrics_prefix: &'static str,
33
+ }
34
+
35
+ impl<'a> TemporalMeter<'a> {
36
+ pub(crate) fn counter(&self, name: &'static str) -> Counter<u64> {
37
+ self.inner
38
+ .u64_counter(self.metrics_prefix.to_string() + name)
39
+ .init()
40
+ }
41
+
42
+ pub(crate) fn histogram(&self, name: &'static str) -> Histogram<u64> {
43
+ self.inner
44
+ .u64_histogram(self.metrics_prefix.to_string() + name)
45
+ .init()
46
+ }
47
+ }
48
+
49
+ impl<'a> ClientMetricProvider for TemporalMeter<'a> {
50
+ fn counter(&self, name: &'static str) -> Counter<u64> {
51
+ self.counter(name)
52
+ }
53
+
54
+ fn histogram(&self, name: &'static str) -> Histogram<u64> {
55
+ self.histogram(name)
56
+ }
57
+ }
58
+
59
+ impl<'a> Deref for TemporalMeter<'a> {
60
+ type Target = dyn ClientMetricProvider + 'a;
61
+
62
+ fn deref(&self) -> &Self::Target {
63
+ self as &Self::Target
64
+ }
65
+ }
66
+
27
67
  struct Instruments {
28
68
  wf_completed_counter: Counter<u64>,
29
69
  wf_canceled_counter: Counter<u64>,
@@ -54,10 +94,10 @@ impl MetricsContext {
54
94
  Self {
55
95
  ctx: Default::default(),
56
96
  kvs: Default::default(),
57
- instruments: Arc::new(Instruments::new_explicit(
97
+ instruments: Arc::new(Instruments::new_explicit(TemporalMeter::new(
58
98
  &NoopMeterProvider::new().meter("fakemeter"),
59
99
  "fakemetrics",
60
- )),
100
+ ))),
61
101
  }
62
102
  }
63
103
 
@@ -257,42 +297,36 @@ impl Instruments {
257
297
  meter
258
298
  } else {
259
299
  no_op_meter = NoopMeterProvider::default().meter("no_op");
260
- &no_op_meter
300
+ TemporalMeter::new(&no_op_meter, "fakemetrics")
261
301
  };
262
- Self::new_explicit(meter, telem.metric_prefix)
302
+ Self::new_explicit(meter)
263
303
  }
264
304
 
265
- fn new_explicit(meter: &Meter, metric_prefix: &'static str) -> Self {
266
- let ctr = |name: &'static str| -> Counter<u64> {
267
- meter.u64_counter(metric_prefix.to_string() + name).init()
268
- };
269
- let hst = |name: &'static str| -> Histogram<u64> {
270
- meter.u64_histogram(metric_prefix.to_string() + name).init()
271
- };
305
+ fn new_explicit(meter: TemporalMeter) -> Self {
272
306
  Self {
273
- wf_completed_counter: ctr("workflow_completed"),
274
- wf_canceled_counter: ctr("workflow_canceled"),
275
- wf_failed_counter: ctr("workflow_failed"),
276
- wf_cont_counter: ctr("workflow_continue_as_new"),
277
- wf_e2e_latency: hst(WF_E2E_LATENCY_NAME),
278
- wf_task_queue_poll_empty_counter: ctr("workflow_task_queue_poll_empty"),
279
- wf_task_queue_poll_succeed_counter: ctr("workflow_task_queue_poll_succeed"),
280
- wf_task_execution_failure_counter: ctr("workflow_task_queue_poll_failed"),
281
- wf_task_sched_to_start_latency: hst(WF_TASK_SCHED_TO_START_LATENCY_NAME),
282
- wf_task_replay_latency: hst(WF_TASK_REPLAY_LATENCY_NAME),
283
- wf_task_execution_latency: hst(WF_TASK_EXECUTION_LATENCY_NAME),
284
- act_poll_no_task: ctr("activity_poll_no_task"),
285
- act_task_received_counter: ctr("activity_task_received"),
286
- act_execution_failed: ctr("activity_execution_failed"),
287
- act_sched_to_start_latency: hst(ACT_SCHED_TO_START_LATENCY_NAME),
288
- act_exec_latency: hst(ACT_EXEC_LATENCY_NAME),
307
+ wf_completed_counter: meter.counter("workflow_completed"),
308
+ wf_canceled_counter: meter.counter("workflow_canceled"),
309
+ wf_failed_counter: meter.counter("workflow_failed"),
310
+ wf_cont_counter: meter.counter("workflow_continue_as_new"),
311
+ wf_e2e_latency: meter.histogram(WF_E2E_LATENCY_NAME),
312
+ wf_task_queue_poll_empty_counter: meter.counter("workflow_task_queue_poll_empty"),
313
+ wf_task_queue_poll_succeed_counter: meter.counter("workflow_task_queue_poll_succeed"),
314
+ wf_task_execution_failure_counter: meter.counter("workflow_task_execution_failed"),
315
+ wf_task_sched_to_start_latency: meter.histogram(WF_TASK_SCHED_TO_START_LATENCY_NAME),
316
+ wf_task_replay_latency: meter.histogram(WF_TASK_REPLAY_LATENCY_NAME),
317
+ wf_task_execution_latency: meter.histogram(WF_TASK_EXECUTION_LATENCY_NAME),
318
+ act_poll_no_task: meter.counter("activity_poll_no_task"),
319
+ act_task_received_counter: meter.counter("activity_task_received"),
320
+ act_execution_failed: meter.counter("activity_execution_failed"),
321
+ act_sched_to_start_latency: meter.histogram(ACT_SCHED_TO_START_LATENCY_NAME),
322
+ act_exec_latency: meter.histogram(ACT_EXEC_LATENCY_NAME),
289
323
  // name kept as worker start for compat with old sdk / what users expect
290
- worker_registered: ctr("worker_start"),
291
- num_pollers: hst(NUM_POLLERS_NAME),
292
- task_slots_available: hst(TASK_SLOTS_AVAILABLE_NAME),
293
- sticky_cache_hit: ctr("sticky_cache_hit"),
294
- sticky_cache_miss: ctr("sticky_cache_miss"),
295
- sticky_cache_size: hst(STICKY_CACHE_SIZE_NAME),
324
+ worker_registered: meter.counter("worker_start"),
325
+ num_pollers: meter.histogram(NUM_POLLERS_NAME),
326
+ task_slots_available: meter.histogram(TASK_SLOTS_AVAILABLE_NAME),
327
+ sticky_cache_hit: meter.counter("sticky_cache_hit"),
328
+ sticky_cache_miss: meter.counter("sticky_cache_miss"),
329
+ sticky_cache_size: meter.histogram(STICKY_CACHE_SIZE_NAME),
296
330
  }
297
331
  }
298
332
  }
@@ -30,6 +30,7 @@ use std::{
30
30
  collections::VecDeque,
31
31
  convert::TryInto,
32
32
  env,
33
+ net::SocketAddr,
33
34
  sync::{
34
35
  atomic::{AtomicBool, Ordering},
35
36
  Arc,
@@ -47,12 +48,10 @@ use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Layer};
47
48
  const TELEM_SERVICE_NAME: &str = "temporal-core-sdk";
48
49
 
49
50
  /// Help you construct an [EnvFilter] compatible filter string which will forward all core module
50
- /// traces at `core_level` and all others (from 3rd party modules, etc) at `other_levl.
51
+ /// traces at `core_level` and all others (from 3rd party modules, etc) at `other_level`.
51
52
  pub fn construct_filter_string(core_level: Level, other_level: Level) -> String {
52
53
  format!(
53
- "{o},temporal_sdk_core={l},temporal_client={l},temporal_sdk={l}",
54
- o = other_level,
55
- l = core_level
54
+ "{other_level},temporal_sdk_core={core_level},temporal_client={core_level},temporal_sdk={core_level}"
56
55
  )
57
56
  }
58
57
 
@@ -62,6 +61,7 @@ pub struct TelemetryInstance {
62
61
  logs_out: Option<Mutex<CoreLogsOut>>,
63
62
  metrics: Option<(Box<dyn MeterProvider + Send + Sync + 'static>, Meter)>,
64
63
  trace_subscriber: Arc<dyn Subscriber + Send + Sync>,
64
+ prom_binding: Option<SocketAddr>,
65
65
  _keepalive_rx: Receiver<()>,
66
66
  }
67
67
 
@@ -71,6 +71,7 @@ impl TelemetryInstance {
71
71
  logs_out: Option<Mutex<CoreLogsOut>>,
72
72
  metric_prefix: &'static str,
73
73
  mut meter_provider: Option<Box<dyn MeterProvider + Send + Sync + 'static>>,
74
+ prom_binding: Option<SocketAddr>,
74
75
  keepalive_rx: Receiver<()>,
75
76
  ) -> Self {
76
77
  let metrics = meter_provider.take().map(|mp| {
@@ -82,6 +83,7 @@ impl TelemetryInstance {
82
83
  logs_out,
83
84
  metrics,
84
85
  trace_subscriber,
86
+ prom_binding,
85
87
  _keepalive_rx: keepalive_rx,
86
88
  }
87
89
  }
@@ -91,6 +93,18 @@ impl TelemetryInstance {
91
93
  pub fn trace_subscriber(&self) -> Arc<dyn Subscriber + Send + Sync> {
92
94
  self.trace_subscriber.clone()
93
95
  }
96
+
97
+ /// Returns the address the Prometheus server is bound to if it is running
98
+ pub fn prom_port(&self) -> Option<SocketAddr> {
99
+ self.prom_binding
100
+ }
101
+
102
+ /// Returns our wrapper for OTel metric meters, can be used to, ex: initialize clients
103
+ pub fn get_metric_meter(&self) -> Option<TemporalMeter> {
104
+ self.metrics
105
+ .as_ref()
106
+ .map(|(_, m)| TemporalMeter::new(m, self.metric_prefix))
107
+ }
94
108
  }
95
109
 
96
110
  thread_local! {
@@ -131,10 +145,6 @@ impl CoreTelemetry for TelemetryInstance {
131
145
  vec![]
132
146
  }
133
147
  }
134
-
135
- fn get_metric_meter(&self) -> Option<&Meter> {
136
- self.metrics.as_ref().map(|(_, m)| m)
137
- }
138
148
  }
139
149
 
140
150
  /// Initialize tracing subscribers/output and logging export, returning a [TelemetryInstance]
@@ -161,6 +171,7 @@ pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyho
161
171
  // Parts of telem dat ====
162
172
  let mut logs_out = None;
163
173
  let metric_prefix = metric_prefix(&opts);
174
+ let mut prom_binding = None;
164
175
  // =======================
165
176
 
166
177
  // Tracing subscriber layers =========
@@ -210,11 +221,14 @@ pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyho
210
221
  let aggregator = SDKAggSelector { metric_prefix };
211
222
  match metrics {
212
223
  MetricsExporter::Prometheus(addr) => {
213
- let srv = PromServer::new(
214
- *addr,
215
- aggregator,
216
- metric_temporality_to_selector(opts.metric_temporality),
217
- )?;
224
+ let srv = runtime.block_on(async move {
225
+ PromServer::new(
226
+ *addr,
227
+ aggregator,
228
+ metric_temporality_to_selector(opts.metric_temporality),
229
+ )
230
+ })?;
231
+ prom_binding = Some(srv.bound_addr());
218
232
  let mp = srv.exporter.meter_provider()?;
219
233
  runtime.spawn(async move { srv.run().await });
220
234
  Some(Box::new(mp) as Box<dyn MeterProvider + Send + Sync>)
@@ -286,6 +300,7 @@ pub fn telemetry_init(opts: TelemetryOptions) -> Result<TelemetryInstance, anyho
286
300
  logs_out,
287
301
  metric_prefix,
288
302
  meter_provider,
303
+ prom_binding,
289
304
  keepalive_rx,
290
305
  ))
291
306
  .expect("Must be able to send telem instance out of thread");
@@ -377,6 +392,7 @@ pub mod test_initters {
377
392
  .unwrap();
378
393
  }
379
394
  }
395
+ use crate::telemetry::metrics::TemporalMeter;
380
396
  #[cfg(test)]
381
397
  pub use test_initters::*;
382
398