@rivetkit/engine 1.0.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 (1392) hide show
  1. package/LICENSE +203 -0
  2. package/artifacts/errors/actor.destroyed_during_creation.json +5 -0
  3. package/artifacts/errors/actor.destroyed_while_waiting_for_ready.json +5 -0
  4. package/artifacts/errors/actor.duplicate_key.json +5 -0
  5. package/artifacts/errors/actor.empty_key.json +5 -0
  6. package/artifacts/errors/actor.input_too_large.json +5 -0
  7. package/artifacts/errors/actor.key_reserved_in_different_datacenter.json +5 -0
  8. package/artifacts/errors/actor.key_too_large.json +5 -0
  9. package/artifacts/errors/actor.kv_key_not_found.json +5 -0
  10. package/artifacts/errors/actor.namespace_not_found.json +5 -0
  11. package/artifacts/errors/actor.no_runners_available.json +5 -0
  12. package/artifacts/errors/actor.not_found.json +5 -0
  13. package/artifacts/errors/api.bad_request.json +5 -0
  14. package/artifacts/errors/api.forbidden.json +5 -0
  15. package/artifacts/errors/api.internal_error.json +5 -0
  16. package/artifacts/errors/api.not_found.json +5 -0
  17. package/artifacts/errors/api.rate_limited.json +5 -0
  18. package/artifacts/errors/api.unauthorized.json +5 -0
  19. package/artifacts/errors/datacenter.not_found.json +5 -0
  20. package/artifacts/errors/guard.actor_destroyed.json +5 -0
  21. package/artifacts/errors/guard.actor_not_found.json +5 -0
  22. package/artifacts/errors/guard.actor_ready_timeout.json +5 -0
  23. package/artifacts/errors/guard.connection_error.json +5 -0
  24. package/artifacts/errors/guard.http_request_build_failed.json +5 -0
  25. package/artifacts/errors/guard.missing_header.json +5 -0
  26. package/artifacts/errors/guard.must_use_regional_host.json +5 -0
  27. package/artifacts/errors/guard.no_route.json +5 -0
  28. package/artifacts/errors/guard.no_route_targets.json +5 -0
  29. package/artifacts/errors/guard.rate_limit.json +5 -0
  30. package/artifacts/errors/guard.request_build_error.json +5 -0
  31. package/artifacts/errors/guard.request_timeout.json +5 -0
  32. package/artifacts/errors/guard.retry_attempts_exceeded.json +5 -0
  33. package/artifacts/errors/guard.service_unavailable.json +5 -0
  34. package/artifacts/errors/guard.target_changed.json +5 -0
  35. package/artifacts/errors/guard.upstream_error.json +5 -0
  36. package/artifacts/errors/guard.uri_parse_error.json +5 -0
  37. package/artifacts/errors/guard.websocket_pending_limit_reached.json +5 -0
  38. package/artifacts/errors/guard.websocket_service_hibernate.json +5 -0
  39. package/artifacts/errors/guard.websocket_service_timeout.json +5 -0
  40. package/artifacts/errors/guard.websocket_service_unavailable.json +5 -0
  41. package/artifacts/errors/guard.wrong_addr_protocol.json +5 -0
  42. package/artifacts/errors/kv.leader_forwarding_failed.json +5 -0
  43. package/artifacts/errors/kv.no_leader_elected.json +5 -0
  44. package/artifacts/errors/kv.not_leader.json +5 -0
  45. package/artifacts/errors/kv.response_channel_closed.json +5 -0
  46. package/artifacts/errors/namespace.failed_to_create.json +5 -0
  47. package/artifacts/errors/namespace.invalid_name.json +5 -0
  48. package/artifacts/errors/namespace.invalid_update.json +5 -0
  49. package/artifacts/errors/namespace.name_not_unique.json +5 -0
  50. package/artifacts/errors/namespace.not_found.json +5 -0
  51. package/artifacts/errors/namespace.not_leader.json +5 -0
  52. package/artifacts/errors/runner.not_found.json +5 -0
  53. package/artifacts/errors/runner_config.invalid.json +5 -0
  54. package/artifacts/errors/runner_config.not_found.json +5 -0
  55. package/artifacts/errors/test.input_too_large.json +5 -0
  56. package/artifacts/errors/test.key_too_large.json +5 -0
  57. package/artifacts/errors/test.meta_error.json +5 -0
  58. package/artifacts/errors/test.not_found.json +5 -0
  59. package/artifacts/errors/test.simple_error.json +5 -0
  60. package/artifacts/errors/test.test_error.json +5 -0
  61. package/artifacts/errors/ups.publish_failed.json +5 -0
  62. package/artifacts/errors/ups.request_timeout.json +5 -0
  63. package/artifacts/errors/validation.invalid_input.json +5 -0
  64. package/artifacts/errors/validation.no_keys.json +5 -0
  65. package/artifacts/errors/validation.race_condition.json +5 -0
  66. package/artifacts/errors/validation.too_many_actor_ids.json +5 -0
  67. package/artifacts/errors/ws.connection_closed.json +5 -0
  68. package/artifacts/errors/ws.eviction.json +5 -0
  69. package/artifacts/errors/ws.invalid_initial_packet.json +5 -0
  70. package/artifacts/errors/ws.invalid_packet.json +5 -0
  71. package/artifacts/errors/ws.invalid_url.json +5 -0
  72. package/artifacts/errors/ws.timed_out_waiting_for_init.json +5 -0
  73. package/artifacts/openapi.json +1833 -0
  74. package/contrib-docs/ACTOR_KEY_RESERVATION.md +101 -0
  75. package/contrib-docs/API.md +11 -0
  76. package/contrib-docs/DOCKER.md +5 -0
  77. package/contrib-docs/ERRORS.md +13 -0
  78. package/contrib-docs/GUARD.md +76 -0
  79. package/contrib-docs/PEGBOARD_TUNNEL_RETRIES.md +83 -0
  80. package/contrib-docs/RUNNER_LIFECYCLE.md +172 -0
  81. package/contrib-docs/SDKS.md +9 -0
  82. package/contrib-docs/TEST_DEPENDENCIES.md +43 -0
  83. package/contrib-docs/design-choicse/EMBEDDED_KV.md +80 -0
  84. package/contrib-docs/operate/TRACING_RECONFIGURE.md +78 -0
  85. package/docker/dev/.gitattributes +1 -0
  86. package/docker/dev/README.md +74 -0
  87. package/docker/dev/clickhouse/client-config.xml +5 -0
  88. package/docker/dev/clickhouse/config.xml +52 -0
  89. package/docker/dev/clickhouse/init/01-create-otel-table.sql +107 -0
  90. package/docker/dev/clickhouse/users.xml +35 -0
  91. package/docker/dev/docker-compose.yml +217 -0
  92. package/docker/dev/grafana/dashboards/api.json +1240 -0
  93. package/docker/dev/grafana/dashboards/cache.json +1075 -0
  94. package/docker/dev/grafana/dashboards/futures.json +230 -0
  95. package/docker/dev/grafana/dashboards/gasoline.json +2477 -0
  96. package/docker/dev/grafana/dashboards/guard.json +1274 -0
  97. package/docker/dev/grafana/dashboards/tokio.json +1005 -0
  98. package/docker/dev/grafana/dashboards/traces.json +957 -0
  99. package/docker/dev/grafana/grafana.ini +14 -0
  100. package/docker/dev/grafana/provisioning/dashboards/dashboards.yaml +10 -0
  101. package/docker/dev/grafana/provisioning/datasources/datasources.yaml +30 -0
  102. package/docker/dev/otel-collector-client/config.yaml +39 -0
  103. package/docker/dev/otel-collector-server/config.yaml +72 -0
  104. package/docker/dev/postgres/init-db.sh +6 -0
  105. package/docker/dev/rivet-engine/config.jsonc +48 -0
  106. package/docker/dev/vector-client/vector.yaml +31 -0
  107. package/docker/dev/vector-server/vector.yaml +61 -0
  108. package/docker/dev-host/.gitattributes +1 -0
  109. package/docker/dev-host/README.md +74 -0
  110. package/docker/dev-host/clickhouse/client-config.xml +5 -0
  111. package/docker/dev-host/clickhouse/config.xml +52 -0
  112. package/docker/dev-host/clickhouse/init/01-create-otel-table.sql +107 -0
  113. package/docker/dev-host/clickhouse/users.xml +35 -0
  114. package/docker/dev-host/docker-compose.yml +190 -0
  115. package/docker/dev-host/grafana/dashboards/api.json +1240 -0
  116. package/docker/dev-host/grafana/dashboards/cache.json +1075 -0
  117. package/docker/dev-host/grafana/dashboards/futures.json +230 -0
  118. package/docker/dev-host/grafana/dashboards/gasoline.json +2477 -0
  119. package/docker/dev-host/grafana/dashboards/guard.json +1274 -0
  120. package/docker/dev-host/grafana/dashboards/tokio.json +1005 -0
  121. package/docker/dev-host/grafana/dashboards/traces.json +957 -0
  122. package/docker/dev-host/grafana/grafana.ini +14 -0
  123. package/docker/dev-host/grafana/provisioning/dashboards/dashboards.yaml +10 -0
  124. package/docker/dev-host/grafana/provisioning/datasources/datasources.yaml +30 -0
  125. package/docker/dev-host/otel-collector-client/config.yaml +39 -0
  126. package/docker/dev-host/otel-collector-server/config.yaml +72 -0
  127. package/docker/dev-host/postgres/init-db.sh +6 -0
  128. package/docker/dev-host/rivet-engine/config.jsonc +48 -0
  129. package/docker/dev-host/vector-client/vector.yaml +31 -0
  130. package/docker/dev-host/vector-server/vector.yaml +61 -0
  131. package/docker/dev-multidc/.gitattributes +1 -0
  132. package/docker/dev-multidc/README.md +86 -0
  133. package/docker/dev-multidc/core/clickhouse/client-config.xml +5 -0
  134. package/docker/dev-multidc/core/clickhouse/config.xml +52 -0
  135. package/docker/dev-multidc/core/clickhouse/init/01-create-otel-table.sql +107 -0
  136. package/docker/dev-multidc/core/clickhouse/users.xml +35 -0
  137. package/docker/dev-multidc/core/grafana/dashboards/api.json +1240 -0
  138. package/docker/dev-multidc/core/grafana/dashboards/cache.json +1075 -0
  139. package/docker/dev-multidc/core/grafana/dashboards/futures.json +230 -0
  140. package/docker/dev-multidc/core/grafana/dashboards/gasoline.json +2477 -0
  141. package/docker/dev-multidc/core/grafana/dashboards/guard.json +1274 -0
  142. package/docker/dev-multidc/core/grafana/dashboards/tokio.json +1005 -0
  143. package/docker/dev-multidc/core/grafana/dashboards/traces.json +957 -0
  144. package/docker/dev-multidc/core/grafana/grafana.ini +14 -0
  145. package/docker/dev-multidc/core/grafana/provisioning/dashboards/dashboards.yaml +10 -0
  146. package/docker/dev-multidc/core/grafana/provisioning/datasources/datasources.yaml +30 -0
  147. package/docker/dev-multidc/datacenters/dc-a/otel-collector-client/config.yaml +39 -0
  148. package/docker/dev-multidc/datacenters/dc-a/otel-collector-server/config.yaml +72 -0
  149. package/docker/dev-multidc/datacenters/dc-a/postgres/init-db.sh +6 -0
  150. package/docker/dev-multidc/datacenters/dc-a/rivet-engine/config.jsonc +62 -0
  151. package/docker/dev-multidc/datacenters/dc-a/vector-client/vector.yaml +31 -0
  152. package/docker/dev-multidc/datacenters/dc-a/vector-server/vector.yaml +61 -0
  153. package/docker/dev-multidc/datacenters/dc-b/otel-collector-client/config.yaml +39 -0
  154. package/docker/dev-multidc/datacenters/dc-b/otel-collector-server/config.yaml +72 -0
  155. package/docker/dev-multidc/datacenters/dc-b/postgres/init-db.sh +6 -0
  156. package/docker/dev-multidc/datacenters/dc-b/rivet-engine/config.jsonc +62 -0
  157. package/docker/dev-multidc/datacenters/dc-b/vector-client/vector.yaml +31 -0
  158. package/docker/dev-multidc/datacenters/dc-b/vector-server/vector.yaml +61 -0
  159. package/docker/dev-multidc/datacenters/dc-c/otel-collector-client/config.yaml +39 -0
  160. package/docker/dev-multidc/datacenters/dc-c/otel-collector-server/config.yaml +72 -0
  161. package/docker/dev-multidc/datacenters/dc-c/postgres/init-db.sh +6 -0
  162. package/docker/dev-multidc/datacenters/dc-c/rivet-engine/config.jsonc +62 -0
  163. package/docker/dev-multidc/datacenters/dc-c/vector-client/vector.yaml +31 -0
  164. package/docker/dev-multidc/datacenters/dc-c/vector-server/vector.yaml +61 -0
  165. package/docker/dev-multidc/docker-compose.yml +546 -0
  166. package/docker/dev-multidc-multinode/.gitattributes +1 -0
  167. package/docker/dev-multidc-multinode/README.md +86 -0
  168. package/docker/dev-multidc-multinode/core/clickhouse/client-config.xml +5 -0
  169. package/docker/dev-multidc-multinode/core/clickhouse/config.xml +52 -0
  170. package/docker/dev-multidc-multinode/core/clickhouse/init/01-create-otel-table.sql +107 -0
  171. package/docker/dev-multidc-multinode/core/clickhouse/users.xml +35 -0
  172. package/docker/dev-multidc-multinode/core/grafana/dashboards/api.json +1240 -0
  173. package/docker/dev-multidc-multinode/core/grafana/dashboards/cache.json +1075 -0
  174. package/docker/dev-multidc-multinode/core/grafana/dashboards/futures.json +230 -0
  175. package/docker/dev-multidc-multinode/core/grafana/dashboards/gasoline.json +2477 -0
  176. package/docker/dev-multidc-multinode/core/grafana/dashboards/guard.json +1274 -0
  177. package/docker/dev-multidc-multinode/core/grafana/dashboards/tokio.json +1005 -0
  178. package/docker/dev-multidc-multinode/core/grafana/dashboards/traces.json +957 -0
  179. package/docker/dev-multidc-multinode/core/grafana/grafana.ini +14 -0
  180. package/docker/dev-multidc-multinode/core/grafana/provisioning/dashboards/dashboards.yaml +10 -0
  181. package/docker/dev-multidc-multinode/core/grafana/provisioning/datasources/datasources.yaml +30 -0
  182. package/docker/dev-multidc-multinode/datacenters/dc-a/otel-collector-client/config.yaml +39 -0
  183. package/docker/dev-multidc-multinode/datacenters/dc-a/otel-collector-server/config.yaml +72 -0
  184. package/docker/dev-multidc-multinode/datacenters/dc-a/postgres/init-db.sh +6 -0
  185. package/docker/dev-multidc-multinode/datacenters/dc-a/rivet-engine/0/config.jsonc +62 -0
  186. package/docker/dev-multidc-multinode/datacenters/dc-a/rivet-engine/1/config.jsonc +62 -0
  187. package/docker/dev-multidc-multinode/datacenters/dc-a/rivet-engine/2/config.jsonc +62 -0
  188. package/docker/dev-multidc-multinode/datacenters/dc-a/vector-client/vector.yaml +31 -0
  189. package/docker/dev-multidc-multinode/datacenters/dc-a/vector-server/vector.yaml +61 -0
  190. package/docker/dev-multidc-multinode/datacenters/dc-b/otel-collector-client/config.yaml +39 -0
  191. package/docker/dev-multidc-multinode/datacenters/dc-b/otel-collector-server/config.yaml +72 -0
  192. package/docker/dev-multidc-multinode/datacenters/dc-b/postgres/init-db.sh +6 -0
  193. package/docker/dev-multidc-multinode/datacenters/dc-b/rivet-engine/0/config.jsonc +62 -0
  194. package/docker/dev-multidc-multinode/datacenters/dc-b/rivet-engine/1/config.jsonc +62 -0
  195. package/docker/dev-multidc-multinode/datacenters/dc-b/rivet-engine/2/config.jsonc +62 -0
  196. package/docker/dev-multidc-multinode/datacenters/dc-b/vector-client/vector.yaml +31 -0
  197. package/docker/dev-multidc-multinode/datacenters/dc-b/vector-server/vector.yaml +61 -0
  198. package/docker/dev-multidc-multinode/datacenters/dc-c/otel-collector-client/config.yaml +39 -0
  199. package/docker/dev-multidc-multinode/datacenters/dc-c/otel-collector-server/config.yaml +72 -0
  200. package/docker/dev-multidc-multinode/datacenters/dc-c/postgres/init-db.sh +6 -0
  201. package/docker/dev-multidc-multinode/datacenters/dc-c/rivet-engine/0/config.jsonc +62 -0
  202. package/docker/dev-multidc-multinode/datacenters/dc-c/rivet-engine/1/config.jsonc +62 -0
  203. package/docker/dev-multidc-multinode/datacenters/dc-c/rivet-engine/2/config.jsonc +62 -0
  204. package/docker/dev-multidc-multinode/datacenters/dc-c/vector-client/vector.yaml +31 -0
  205. package/docker/dev-multidc-multinode/datacenters/dc-c/vector-server/vector.yaml +61 -0
  206. package/docker/dev-multidc-multinode/docker-compose.yml +888 -0
  207. package/docker/dev-multinode/.gitattributes +1 -0
  208. package/docker/dev-multinode/README.md +74 -0
  209. package/docker/dev-multinode/clickhouse/client-config.xml +5 -0
  210. package/docker/dev-multinode/clickhouse/config.xml +52 -0
  211. package/docker/dev-multinode/clickhouse/init/01-create-otel-table.sql +107 -0
  212. package/docker/dev-multinode/clickhouse/users.xml +35 -0
  213. package/docker/dev-multinode/docker-compose.yml +323 -0
  214. package/docker/dev-multinode/grafana/dashboards/api.json +1240 -0
  215. package/docker/dev-multinode/grafana/dashboards/cache.json +1075 -0
  216. package/docker/dev-multinode/grafana/dashboards/futures.json +230 -0
  217. package/docker/dev-multinode/grafana/dashboards/gasoline.json +2477 -0
  218. package/docker/dev-multinode/grafana/dashboards/guard.json +1274 -0
  219. package/docker/dev-multinode/grafana/dashboards/tokio.json +1005 -0
  220. package/docker/dev-multinode/grafana/dashboards/traces.json +957 -0
  221. package/docker/dev-multinode/grafana/grafana.ini +14 -0
  222. package/docker/dev-multinode/grafana/provisioning/dashboards/dashboards.yaml +10 -0
  223. package/docker/dev-multinode/grafana/provisioning/datasources/datasources.yaml +30 -0
  224. package/docker/dev-multinode/otel-collector-client/config.yaml +39 -0
  225. package/docker/dev-multinode/otel-collector-server/config.yaml +72 -0
  226. package/docker/dev-multinode/postgres/init-db.sh +6 -0
  227. package/docker/dev-multinode/rivet-engine/0/config.jsonc +48 -0
  228. package/docker/dev-multinode/rivet-engine/1/config.jsonc +48 -0
  229. package/docker/dev-multinode/rivet-engine/2/config.jsonc +48 -0
  230. package/docker/dev-multinode/vector-client/vector.yaml +31 -0
  231. package/docker/dev-multinode/vector-server/vector.yaml +61 -0
  232. package/docker/engine/build.sh +67 -0
  233. package/docker/engine/linux-aarch64.Dockerfile +97 -0
  234. package/docker/engine/linux-x86_64.Dockerfile +93 -0
  235. package/docker/engine/macos-aarch64.Dockerfile +92 -0
  236. package/docker/engine/macos-x86_64.Dockerfile +92 -0
  237. package/docker/engine/windows.Dockerfile +80 -0
  238. package/docker/prod-file-system/.gitattributes +1 -0
  239. package/docker/prod-file-system/README.md +76 -0
  240. package/docker/prod-file-system/docker-compose.yml +41 -0
  241. package/docker/prod-file-system/rivet-engine/config.jsonc +2 -0
  242. package/docker/template/README.md +20 -0
  243. package/docker/template/grafana-dashboards/api.json +1240 -0
  244. package/docker/template/grafana-dashboards/cache.json +1075 -0
  245. package/docker/template/grafana-dashboards/futures.json +230 -0
  246. package/docker/template/grafana-dashboards/gasoline.json +2477 -0
  247. package/docker/template/grafana-dashboards/guard.json +1274 -0
  248. package/docker/template/grafana-dashboards/tokio.json +1005 -0
  249. package/docker/template/grafana-dashboards/traces.json +957 -0
  250. package/docker/template/node_modules/.bin/js-yaml +21 -0
  251. package/docker/template/node_modules/.bin/tsc +21 -0
  252. package/docker/template/node_modules/.bin/tsserver +21 -0
  253. package/docker/template/node_modules/.bin/tsx +21 -0
  254. package/docker/template/package.json +23 -0
  255. package/docker/template/src/config.ts +104 -0
  256. package/docker/template/src/context.ts +216 -0
  257. package/docker/template/src/docker-compose.ts +368 -0
  258. package/docker/template/src/git.ts +8 -0
  259. package/docker/template/src/main.ts +65 -0
  260. package/docker/template/src/readme.ts +98 -0
  261. package/docker/template/src/services/core/clickhouse.ts +223 -0
  262. package/docker/template/src/services/core/grafana.ts +115 -0
  263. package/docker/template/src/services/edge/otel-collector-client.ts +64 -0
  264. package/docker/template/src/services/edge/otel-collector-server.ts +107 -0
  265. package/docker/template/src/services/edge/postgres.ts +23 -0
  266. package/docker/template/src/services/edge/rivet-engine.ts +87 -0
  267. package/docker/template/src/services/edge/runner.ts +7 -0
  268. package/docker/template/src/services/edge/vector-client.ts +55 -0
  269. package/docker/template/src/services/edge/vector-server.ts +111 -0
  270. package/docker/template/src/utils.ts +19 -0
  271. package/docker/template/tsconfig.json +18 -0
  272. package/docker/universal/Dockerfile +133 -0
  273. package/package.json +10 -0
  274. package/packages/actor-kv/Cargo.toml +31 -0
  275. package/packages/actor-kv/src/entry.rs +147 -0
  276. package/packages/actor-kv/src/key.rs +81 -0
  277. package/packages/actor-kv/src/lib.rs +357 -0
  278. package/packages/actor-kv/src/utils.rs +101 -0
  279. package/packages/actor-kv/tests/kv_operations.rs +294 -0
  280. package/packages/actor-kv/tests/list_edge_cases.rs +370 -0
  281. package/packages/api-builder/Cargo.toml +36 -0
  282. package/packages/api-builder/src/context.rs +98 -0
  283. package/packages/api-builder/src/error_response.rs +116 -0
  284. package/packages/api-builder/src/errors.rs +29 -0
  285. package/packages/api-builder/src/extract.rs +137 -0
  286. package/packages/api-builder/src/global_context.rs +31 -0
  287. package/packages/api-builder/src/lib.rs +19 -0
  288. package/packages/api-builder/src/metrics.rs +29 -0
  289. package/packages/api-builder/src/middleware.rs +232 -0
  290. package/packages/api-builder/src/prelude.rs +18 -0
  291. package/packages/api-builder/src/request_ids.rs +17 -0
  292. package/packages/api-builder/src/router.rs +89 -0
  293. package/packages/api-builder/src/wrappers.rs +138 -0
  294. package/packages/api-builder/tests/basic.rs +215 -0
  295. package/packages/api-builder/tests/errors.rs +104 -0
  296. package/packages/api-peer/Cargo.toml +34 -0
  297. package/packages/api-peer/src/actors/create.rs +40 -0
  298. package/packages/api-peer/src/actors/delete.rs +87 -0
  299. package/packages/api-peer/src/actors/kv_get.rs +67 -0
  300. package/packages/api-peer/src/actors/list.rs +98 -0
  301. package/packages/api-peer/src/actors/list_names.rs +56 -0
  302. package/packages/api-peer/src/actors/mod.rs +5 -0
  303. package/packages/api-peer/src/internal.rs +186 -0
  304. package/packages/api-peer/src/lib.rs +28 -0
  305. package/packages/api-peer/src/namespaces.rs +122 -0
  306. package/packages/api-peer/src/router.rs +51 -0
  307. package/packages/api-peer/src/runner_configs.rs +160 -0
  308. package/packages/api-peer/src/runners.rs +109 -0
  309. package/packages/api-public/Cargo.toml +38 -0
  310. package/packages/api-public/build.rs +45 -0
  311. package/packages/api-public/src/actors/create.rs +99 -0
  312. package/packages/api-public/src/actors/delete.rs +86 -0
  313. package/packages/api-public/src/actors/get_or_create.rs +170 -0
  314. package/packages/api-public/src/actors/kv_get.rs +79 -0
  315. package/packages/api-public/src/actors/list.rs +241 -0
  316. package/packages/api-public/src/actors/list_names.rs +76 -0
  317. package/packages/api-public/src/actors/mod.rs +7 -0
  318. package/packages/api-public/src/actors/utils.rs +216 -0
  319. package/packages/api-public/src/ctx.rs +70 -0
  320. package/packages/api-public/src/datacenters.rs +43 -0
  321. package/packages/api-public/src/errors.rs +30 -0
  322. package/packages/api-public/src/health.rs +166 -0
  323. package/packages/api-public/src/lib.rs +13 -0
  324. package/packages/api-public/src/metadata.rs +24 -0
  325. package/packages/api-public/src/namespaces.rs +89 -0
  326. package/packages/api-public/src/router.rs +182 -0
  327. package/packages/api-public/src/runner_configs/delete.rs +99 -0
  328. package/packages/api-public/src/runner_configs/list.rs +98 -0
  329. package/packages/api-public/src/runner_configs/mod.rs +12 -0
  330. package/packages/api-public/src/runner_configs/refresh_metadata.rs +116 -0
  331. package/packages/api-public/src/runner_configs/serverless_health_check.rs +81 -0
  332. package/packages/api-public/src/runner_configs/upsert.rs +194 -0
  333. package/packages/api-public/src/runner_configs/utils.rs +217 -0
  334. package/packages/api-public/src/runners.rs +144 -0
  335. package/packages/api-public/src/ui.rs +44 -0
  336. package/packages/api-types/Cargo.toml +17 -0
  337. package/packages/api-types/src/actors/create.rs +29 -0
  338. package/packages/api-types/src/actors/list.rs +23 -0
  339. package/packages/api-types/src/actors/list_names.rs +24 -0
  340. package/packages/api-types/src/actors/mod.rs +3 -0
  341. package/packages/api-types/src/datacenters/list.rs +12 -0
  342. package/packages/api-types/src/datacenters/mod.rs +1 -0
  343. package/packages/api-types/src/lib.rs +6 -0
  344. package/packages/api-types/src/namespaces/list.rs +21 -0
  345. package/packages/api-types/src/namespaces/mod.rs +2 -0
  346. package/packages/api-types/src/namespaces/runner_configs.rs +55 -0
  347. package/packages/api-types/src/pagination.rs +8 -0
  348. package/packages/api-types/src/runner_configs/list.rs +29 -0
  349. package/packages/api-types/src/runner_configs/mod.rs +1 -0
  350. package/packages/api-types/src/runners/list.rs +25 -0
  351. package/packages/api-types/src/runners/mod.rs +1 -0
  352. package/packages/api-util/Cargo.toml +22 -0
  353. package/packages/api-util/src/errors.rs +9 -0
  354. package/packages/api-util/src/lib.rs +209 -0
  355. package/packages/bootstrap/Cargo.toml +19 -0
  356. package/packages/bootstrap/src/lib.rs +102 -0
  357. package/packages/cache/Cargo.toml +28 -0
  358. package/packages/cache/src/driver.rs +346 -0
  359. package/packages/cache/src/errors.rs +23 -0
  360. package/packages/cache/src/getter_ctx.rs +138 -0
  361. package/packages/cache/src/inner.rs +60 -0
  362. package/packages/cache/src/key.rs +101 -0
  363. package/packages/cache/src/lib.rs +19 -0
  364. package/packages/cache/src/metrics.rs +34 -0
  365. package/packages/cache/src/purge.rs +13 -0
  366. package/packages/cache/src/rate_limit.rs +109 -0
  367. package/packages/cache/src/req_config.rs +443 -0
  368. package/packages/cache/tests/integration.rs +582 -0
  369. package/packages/cache-purge/Cargo.toml +17 -0
  370. package/packages/cache-purge/src/lib.rs +44 -0
  371. package/packages/cache-result/Cargo.toml +9 -0
  372. package/packages/cache-result/src/lib.rs +61 -0
  373. package/packages/clickhouse-inserter/Cargo.toml +17 -0
  374. package/packages/clickhouse-inserter/src/error.rs +16 -0
  375. package/packages/clickhouse-inserter/src/lib.rs +179 -0
  376. package/packages/clickhouse-user-query/Cargo.toml +16 -0
  377. package/packages/clickhouse-user-query/examples/case_sensitivity_demo.rs +100 -0
  378. package/packages/clickhouse-user-query/examples/group_by_example.rs +53 -0
  379. package/packages/clickhouse-user-query/examples/string_contains_demo.rs +96 -0
  380. package/packages/clickhouse-user-query/src/builder.rs +445 -0
  381. package/packages/clickhouse-user-query/src/error.rs +37 -0
  382. package/packages/clickhouse-user-query/src/lib.rs +61 -0
  383. package/packages/clickhouse-user-query/src/query.rs +143 -0
  384. package/packages/clickhouse-user-query/src/schema.rs +78 -0
  385. package/packages/clickhouse-user-query/tests/builder_tests.rs +619 -0
  386. package/packages/clickhouse-user-query/tests/case_sensitivity_tests.rs +307 -0
  387. package/packages/clickhouse-user-query/tests/integration_tests.rs +540 -0
  388. package/packages/clickhouse-user-query/tests/query_tests.rs +263 -0
  389. package/packages/clickhouse-user-query/tests/schema_tests.rs +44 -0
  390. package/packages/config/Cargo.toml +20 -0
  391. package/packages/config/src/config/api_peer.rs +21 -0
  392. package/packages/config/src/config/api_public.rs +25 -0
  393. package/packages/config/src/config/auth.rs +10 -0
  394. package/packages/config/src/config/cache.rs +24 -0
  395. package/packages/config/src/config/clickhouse.rs +49 -0
  396. package/packages/config/src/config/db.rs +52 -0
  397. package/packages/config/src/config/guard.rs +42 -0
  398. package/packages/config/src/config/logs.rs +10 -0
  399. package/packages/config/src/config/mod.rs +240 -0
  400. package/packages/config/src/config/pegboard.rs +94 -0
  401. package/packages/config/src/config/pubsub.rs +90 -0
  402. package/packages/config/src/config/runtime.rs +31 -0
  403. package/packages/config/src/config/telemetry.rs +14 -0
  404. package/packages/config/src/config/topology.rs +123 -0
  405. package/packages/config/src/config/vector.rs +18 -0
  406. package/packages/config/src/defaults.rs +11 -0
  407. package/packages/config/src/lib.rs +135 -0
  408. package/packages/config/src/paths.rs +25 -0
  409. package/packages/config/src/secret.rs +72 -0
  410. package/packages/dump-openapi/Cargo.toml +11 -0
  411. package/packages/dump-openapi/build.rs +26 -0
  412. package/packages/dump-openapi/src/lib.rs +1 -0
  413. package/packages/engine/Cargo.toml +74 -0
  414. package/packages/engine/src/commands/config.rs +18 -0
  415. package/packages/engine/src/commands/db/mod.rs +80 -0
  416. package/packages/engine/src/commands/mod.rs +7 -0
  417. package/packages/engine/src/commands/start.rs +143 -0
  418. package/packages/engine/src/commands/tracing.rs +86 -0
  419. package/packages/engine/src/commands/udb/cli.rs +562 -0
  420. package/packages/engine/src/commands/udb/mod.rs +132 -0
  421. package/packages/engine/src/commands/udb_keys.rs +200 -0
  422. package/packages/engine/src/commands/wf/mod.rs +125 -0
  423. package/packages/engine/src/commands/wf/signal.rs +80 -0
  424. package/packages/engine/src/keys.rs +47 -0
  425. package/packages/engine/src/lib.rs +55 -0
  426. package/packages/engine/src/main.rs +60 -0
  427. package/packages/engine/src/run_config.rs +53 -0
  428. package/packages/engine/src/util/db.rs +99 -0
  429. package/packages/engine/src/util/format.rs +69 -0
  430. package/packages/engine/src/util/mod.rs +13 -0
  431. package/packages/engine/src/util/udb.rs +687 -0
  432. package/packages/engine/src/util/wf/mod.rs +649 -0
  433. package/packages/engine/src/util/wf/signal.rs +126 -0
  434. package/packages/engine/tests/actors_create.rs +524 -0
  435. package/packages/engine/tests/actors_delete.rs +243 -0
  436. package/packages/engine/tests/actors_general.rs +191 -0
  437. package/packages/engine/tests/actors_get.rs +230 -0
  438. package/packages/engine/tests/actors_get_by_id.rs +170 -0
  439. package/packages/engine/tests/actors_get_or_create.rs +294 -0
  440. package/packages/engine/tests/actors_get_or_create_by_id.rs +147 -0
  441. package/packages/engine/tests/actors_lifecycle.rs +165 -0
  442. package/packages/engine/tests/actors_list.rs +798 -0
  443. package/packages/engine/tests/actors_list_names.rs +353 -0
  444. package/packages/engine/tests/common/actors.rs +554 -0
  445. package/packages/engine/tests/common/ctx.rs +201 -0
  446. package/packages/engine/tests/common/mod.rs +30 -0
  447. package/packages/engine/tests/common/ns.rs +36 -0
  448. package/packages/engine/tests/common/runner.rs +134 -0
  449. package/packages/engine/tests/common/test_helpers.rs +226 -0
  450. package/packages/engine/tests/runners_dupe_key.rs +27 -0
  451. package/packages/engine/tests/runners_version.rs +50 -0
  452. package/packages/env/Cargo.toml +14 -0
  453. package/packages/env/build.rs +8 -0
  454. package/packages/env/src/lib.rs +30 -0
  455. package/packages/epoxy/Cargo.toml +45 -0
  456. package/packages/epoxy/README.md +158 -0
  457. package/packages/epoxy/spec/KEYS.md +33 -0
  458. package/packages/epoxy/spec/PROPOSAL.md +125 -0
  459. package/packages/epoxy/spec/RECONFIGURE.md +40 -0
  460. package/packages/epoxy/src/consts.rs +42 -0
  461. package/packages/epoxy/src/errors.rs +21 -0
  462. package/packages/epoxy/src/http_client.rs +192 -0
  463. package/packages/epoxy/src/http_routes.rs +34 -0
  464. package/packages/epoxy/src/keys/keys.rs +99 -0
  465. package/packages/epoxy/src/keys/mod.rs +9 -0
  466. package/packages/epoxy/src/keys/replica.rs +283 -0
  467. package/packages/epoxy/src/lib.rs +25 -0
  468. package/packages/epoxy/src/ops/explicit_prepare.rs +342 -0
  469. package/packages/epoxy/src/ops/kv/get_local.rs +44 -0
  470. package/packages/epoxy/src/ops/kv/get_optimistic.rs +150 -0
  471. package/packages/epoxy/src/ops/kv/mod.rs +3 -0
  472. package/packages/epoxy/src/ops/kv/purge_local.rs +28 -0
  473. package/packages/epoxy/src/ops/mod.rs +4 -0
  474. package/packages/epoxy/src/ops/propose.rs +352 -0
  475. package/packages/epoxy/src/ops/read_cluster_config.rs +24 -0
  476. package/packages/epoxy/src/replica/ballot.rs +130 -0
  477. package/packages/epoxy/src/replica/commit_kv.rs +80 -0
  478. package/packages/epoxy/src/replica/decide_path.rs +51 -0
  479. package/packages/epoxy/src/replica/lead_consensus.rs +65 -0
  480. package/packages/epoxy/src/replica/log.rs +84 -0
  481. package/packages/epoxy/src/replica/message_request.rs +166 -0
  482. package/packages/epoxy/src/replica/messages/accept.rs +50 -0
  483. package/packages/epoxy/src/replica/messages/accepted.rs +35 -0
  484. package/packages/epoxy/src/replica/messages/commit.rs +46 -0
  485. package/packages/epoxy/src/replica/messages/committed.rs +41 -0
  486. package/packages/epoxy/src/replica/messages/download_instances.rs +69 -0
  487. package/packages/epoxy/src/replica/messages/mod.rs +15 -0
  488. package/packages/epoxy/src/replica/messages/pre_accept.rs +69 -0
  489. package/packages/epoxy/src/replica/messages/prepare.rs +89 -0
  490. package/packages/epoxy/src/replica/mod.rs +11 -0
  491. package/packages/epoxy/src/replica/update_config.rs +24 -0
  492. package/packages/epoxy/src/replica/utils.rs +111 -0
  493. package/packages/epoxy/src/types.rs +117 -0
  494. package/packages/epoxy/src/utils.rs +65 -0
  495. package/packages/epoxy/src/workflows/coordinator/mod.rs +121 -0
  496. package/packages/epoxy/src/workflows/coordinator/reconfigure.rs +291 -0
  497. package/packages/epoxy/src/workflows/coordinator/replica_status_change.rs +193 -0
  498. package/packages/epoxy/src/workflows/mod.rs +3 -0
  499. package/packages/epoxy/src/workflows/purger.rs +81 -0
  500. package/packages/epoxy/src/workflows/replica/mod.rs +39 -0
  501. package/packages/epoxy/src/workflows/replica/setup.rs +823 -0
  502. package/packages/epoxy/tests/common/api.rs +25 -0
  503. package/packages/epoxy/tests/common/mod.rs +301 -0
  504. package/packages/epoxy/tests/common/utils.rs +23 -0
  505. package/packages/epoxy/tests/kv.rs +187 -0
  506. package/packages/epoxy/tests/kv_get_optimistic.rs +179 -0
  507. package/packages/epoxy/tests/proposal.rs +38 -0
  508. package/packages/epoxy/tests/reconfigure.rs +618 -0
  509. package/packages/error/Cargo.toml +16 -0
  510. package/packages/error/src/error.rs +90 -0
  511. package/packages/error/src/lib.rs +13 -0
  512. package/packages/error/src/schema.rs +86 -0
  513. package/packages/error/tests/basic.rs +338 -0
  514. package/packages/error-macros/Cargo.toml +19 -0
  515. package/packages/error-macros/src/lib.rs +632 -0
  516. package/packages/gasoline/Cargo.toml +55 -0
  517. package/packages/gasoline/src/activity.rs +24 -0
  518. package/packages/gasoline/src/builder/common/message.rs +104 -0
  519. package/packages/gasoline/src/builder/common/mod.rs +5 -0
  520. package/packages/gasoline/src/builder/common/signal.rs +193 -0
  521. package/packages/gasoline/src/builder/common/workflow.rs +196 -0
  522. package/packages/gasoline/src/builder/mod.rs +60 -0
  523. package/packages/gasoline/src/builder/workflow/message.rs +147 -0
  524. package/packages/gasoline/src/builder/workflow/mod.rs +5 -0
  525. package/packages/gasoline/src/builder/workflow/signal.rs +227 -0
  526. package/packages/gasoline/src/builder/workflow/sub_workflow.rs +318 -0
  527. package/packages/gasoline/src/ctx/activity.rs +192 -0
  528. package/packages/gasoline/src/ctx/common.rs +153 -0
  529. package/packages/gasoline/src/ctx/listen.rs +121 -0
  530. package/packages/gasoline/src/ctx/message.rs +346 -0
  531. package/packages/gasoline/src/ctx/mod.rs +18 -0
  532. package/packages/gasoline/src/ctx/operation.rs +191 -0
  533. package/packages/gasoline/src/ctx/standalone.rs +228 -0
  534. package/packages/gasoline/src/ctx/test.rs +251 -0
  535. package/packages/gasoline/src/ctx/versioned_workflow.rs +198 -0
  536. package/packages/gasoline/src/ctx/workflow.rs +1459 -0
  537. package/packages/gasoline/src/db/debug.rs +199 -0
  538. package/packages/gasoline/src/db/kv/debug.rs +1493 -0
  539. package/packages/gasoline/src/db/kv/keys/history.rs +1780 -0
  540. package/packages/gasoline/src/db/kv/keys/metric.rs +170 -0
  541. package/packages/gasoline/src/db/kv/keys/mod.rs +6 -0
  542. package/packages/gasoline/src/db/kv/keys/signal.rs +401 -0
  543. package/packages/gasoline/src/db/kv/keys/wake.rs +310 -0
  544. package/packages/gasoline/src/db/kv/keys/worker.rs +185 -0
  545. package/packages/gasoline/src/db/kv/keys/workflow.rs +1175 -0
  546. package/packages/gasoline/src/db/kv/mod.rs +3044 -0
  547. package/packages/gasoline/src/db/kv/subjects.rs +13 -0
  548. package/packages/gasoline/src/db/kv/system.rs +33 -0
  549. package/packages/gasoline/src/db/mod.rs +344 -0
  550. package/packages/gasoline/src/error.rs +258 -0
  551. package/packages/gasoline/src/executable.rs +186 -0
  552. package/packages/gasoline/src/history/cursor.rs +779 -0
  553. package/packages/gasoline/src/history/event.rs +210 -0
  554. package/packages/gasoline/src/history/location.rs +185 -0
  555. package/packages/gasoline/src/history/mod.rs +8 -0
  556. package/packages/gasoline/src/history/removed.rs +94 -0
  557. package/packages/gasoline/src/lib.rs +18 -0
  558. package/packages/gasoline/src/listen.rs +24 -0
  559. package/packages/gasoline/src/message.rs +103 -0
  560. package/packages/gasoline/src/metrics.rs +156 -0
  561. package/packages/gasoline/src/operation.rs +21 -0
  562. package/packages/gasoline/src/prelude.rs +53 -0
  563. package/packages/gasoline/src/registry.rs +111 -0
  564. package/packages/gasoline/src/signal.rs +117 -0
  565. package/packages/gasoline/src/stub.rs +118 -0
  566. package/packages/gasoline/src/utils/mod.rs +20 -0
  567. package/packages/gasoline/src/utils/tags.rs +82 -0
  568. package/packages/gasoline/src/utils/time.rs +85 -0
  569. package/packages/gasoline/src/worker.rs +336 -0
  570. package/packages/gasoline/src/workflow.rs +64 -0
  571. package/packages/gasoline/tests/activity_ctx.rs +83 -0
  572. package/packages/gasoline/tests/workflow_ctx.rs +288 -0
  573. package/packages/gasoline/tests/workflows/activity_test.rs +33 -0
  574. package/packages/gasoline/tests/workflows/basic.rs +13 -0
  575. package/packages/gasoline/tests/workflows/eviction_test.rs +45 -0
  576. package/packages/gasoline/tests/workflows/listen_timeout.rs +27 -0
  577. package/packages/gasoline/tests/workflows/loop_test.rs +30 -0
  578. package/packages/gasoline/tests/workflows/mod.rs +11 -0
  579. package/packages/gasoline/tests/workflows/properties_test.rs +56 -0
  580. package/packages/gasoline/tests/workflows/signal_test.rs +24 -0
  581. package/packages/gasoline/tests/workflows/sleep_test.rs +15 -0
  582. package/packages/gasoline/tests/workflows/state_test.rs +69 -0
  583. package/packages/gasoline/tests/workflows/sub_test.rs +21 -0
  584. package/packages/gasoline/tests/workflows/tags_test.rs +40 -0
  585. package/packages/gasoline-macros/Cargo.toml +14 -0
  586. package/packages/gasoline-macros/src/lib.rs +527 -0
  587. package/packages/guard/Cargo.toml +56 -0
  588. package/packages/guard/src/cache/actor.rs +43 -0
  589. package/packages/guard/src/cache/mod.rs +69 -0
  590. package/packages/guard/src/errors.rs +62 -0
  591. package/packages/guard/src/lib.rs +58 -0
  592. package/packages/guard/src/middleware.rs +42 -0
  593. package/packages/guard/src/routing/api_public.rs +70 -0
  594. package/packages/guard/src/routing/mod.rs +245 -0
  595. package/packages/guard/src/routing/pegboard_gateway.rs +260 -0
  596. package/packages/guard/src/routing/runner.rs +129 -0
  597. package/packages/guard/src/shared_state.rs +31 -0
  598. package/packages/guard/src/tls.rs +224 -0
  599. package/packages/guard/tests/parse_actor_path.rs +240 -0
  600. package/packages/guard-core/Cargo.toml +58 -0
  601. package/packages/guard-core/src/analytics.rs +46 -0
  602. package/packages/guard-core/src/cert_resolver.rs +61 -0
  603. package/packages/guard-core/src/custom_serve.rs +52 -0
  604. package/packages/guard-core/src/errors.rs +113 -0
  605. package/packages/guard-core/src/lib.rs +25 -0
  606. package/packages/guard-core/src/metrics.rs +64 -0
  607. package/packages/guard-core/src/proxy_service.rs +2699 -0
  608. package/packages/guard-core/src/request_context.rs +184 -0
  609. package/packages/guard-core/src/server.rs +289 -0
  610. package/packages/guard-core/src/task_group.rs +57 -0
  611. package/packages/guard-core/src/types.rs +19 -0
  612. package/packages/guard-core/src/websocket_handle.rs +47 -0
  613. package/packages/guard-core/tests/common/mod.rs +678 -0
  614. package/packages/guard-core/tests/custom_serve.rs +392 -0
  615. package/packages/guard-core/tests/fixtures/tls/README.md +6 -0
  616. package/packages/guard-core/tests/fixtures/tls/api_cert.pem +51 -0
  617. package/packages/guard-core/tests/fixtures/tls/api_key.pem +7 -0
  618. package/packages/guard-core/tests/fixtures/tls/job_cert.pem +55 -0
  619. package/packages/guard-core/tests/fixtures/tls/job_key.pem +7 -0
  620. package/packages/guard-core/tests/https.rs +400 -0
  621. package/packages/guard-core/tests/metrics.rs +247 -0
  622. package/packages/guard-core/tests/proxy.rs +842 -0
  623. package/packages/guard-core/tests/simple_websocket.rs +258 -0
  624. package/packages/guard-core/tests/simple_websocket_echo.rs +318 -0
  625. package/packages/guard-core/tests/simple_websocket_test2.rs +120 -0
  626. package/packages/guard-core/tests/streaming_response.rs +265 -0
  627. package/packages/guard-core/tests/websocket.rs +1113 -0
  628. package/packages/internal/Cargo.toml +13 -0
  629. package/packages/internal/README.md +1 -0
  630. package/packages/internal/src/lib.rs +1 -0
  631. package/packages/internal/src/ops/bump_serverless_autoscaler_global.rs +64 -0
  632. package/packages/internal/src/ops/cache/mod.rs +1 -0
  633. package/packages/internal/src/ops/cache/purge_global.rs +81 -0
  634. package/packages/internal/src/ops/mod.rs +2 -0
  635. package/packages/logs/Cargo.toml +20 -0
  636. package/packages/logs/src/lib.rs +9 -0
  637. package/packages/logs/src/unix.rs +201 -0
  638. package/packages/logs/src/windows.rs +240 -0
  639. package/packages/metrics/Cargo.toml +20 -0
  640. package/packages/metrics/src/buckets.rs +32 -0
  641. package/packages/metrics/src/lib.rs +8 -0
  642. package/packages/metrics/src/providers.rs +183 -0
  643. package/packages/namespace/Cargo.toml +28 -0
  644. package/packages/namespace/src/errors.rs +39 -0
  645. package/packages/namespace/src/keys/mod.rs +190 -0
  646. package/packages/namespace/src/keys/runner_config.rs +211 -0
  647. package/packages/namespace/src/lib.rs +16 -0
  648. package/packages/namespace/src/ops/get_global.rs +58 -0
  649. package/packages/namespace/src/ops/get_local.rs +69 -0
  650. package/packages/namespace/src/ops/list.rs +69 -0
  651. package/packages/namespace/src/ops/mod.rs +6 -0
  652. package/packages/namespace/src/ops/resolve_for_name_global.rs +57 -0
  653. package/packages/namespace/src/ops/resolve_for_name_local.rs +41 -0
  654. package/packages/namespace/src/ops/runner_config/delete.rs +53 -0
  655. package/packages/namespace/src/ops/runner_config/get.rs +94 -0
  656. package/packages/namespace/src/ops/runner_config/list.rs +94 -0
  657. package/packages/namespace/src/ops/runner_config/mod.rs +4 -0
  658. package/packages/namespace/src/ops/runner_config/upsert.rs +148 -0
  659. package/packages/namespace/src/utils.rs +11 -0
  660. package/packages/namespace/src/workflows/mod.rs +1 -0
  661. package/packages/namespace/src/workflows/namespace.rs +178 -0
  662. package/packages/pegboard/Cargo.toml +34 -0
  663. package/packages/pegboard/src/errors.rs +76 -0
  664. package/packages/pegboard/src/keys/actor.rs +443 -0
  665. package/packages/pegboard/src/keys/epoxy/mod.rs +1 -0
  666. package/packages/pegboard/src/keys/epoxy/ns.rs +68 -0
  667. package/packages/pegboard/src/keys/hibernating_request.rs +72 -0
  668. package/packages/pegboard/src/keys/mod.rs +15 -0
  669. package/packages/pegboard/src/keys/ns.rs +1367 -0
  670. package/packages/pegboard/src/keys/runner.rs +818 -0
  671. package/packages/pegboard/src/lib.rs +19 -0
  672. package/packages/pegboard/src/metrics.rs +19 -0
  673. package/packages/pegboard/src/ops/actor/create.rs +159 -0
  674. package/packages/pegboard/src/ops/actor/get.rs +100 -0
  675. package/packages/pegboard/src/ops/actor/get_for_gateway.rs +70 -0
  676. package/packages/pegboard/src/ops/actor/get_for_key.rs +93 -0
  677. package/packages/pegboard/src/ops/actor/get_reservation_for_key.rs +46 -0
  678. package/packages/pegboard/src/ops/actor/get_runner.rs +64 -0
  679. package/packages/pegboard/src/ops/actor/hibernating_request/delete.rs +41 -0
  680. package/packages/pegboard/src/ops/actor/hibernating_request/list.rs +65 -0
  681. package/packages/pegboard/src/ops/actor/hibernating_request/mod.rs +3 -0
  682. package/packages/pegboard/src/ops/actor/hibernating_request/upsert.rs +51 -0
  683. package/packages/pegboard/src/ops/actor/list_for_ns.rs +207 -0
  684. package/packages/pegboard/src/ops/actor/list_names.rs +62 -0
  685. package/packages/pegboard/src/ops/actor/mod.rs +9 -0
  686. package/packages/pegboard/src/ops/mod.rs +2 -0
  687. package/packages/pegboard/src/ops/runner/find_dc_with_runner.rs +222 -0
  688. package/packages/pegboard/src/ops/runner/get.rs +143 -0
  689. package/packages/pegboard/src/ops/runner/get_by_key.rs +51 -0
  690. package/packages/pegboard/src/ops/runner/list_for_ns.rs +209 -0
  691. package/packages/pegboard/src/ops/runner/list_names.rs +60 -0
  692. package/packages/pegboard/src/ops/runner/mod.rs +6 -0
  693. package/packages/pegboard/src/ops/runner/update_alloc_idx.rs +208 -0
  694. package/packages/pegboard/src/pubsub_subjects.rs +80 -0
  695. package/packages/pegboard/src/utils.rs +29 -0
  696. package/packages/pegboard/src/workflows/actor/destroy.rs +264 -0
  697. package/packages/pegboard/src/workflows/actor/keys.rs +283 -0
  698. package/packages/pegboard/src/workflows/actor/mod.rs +804 -0
  699. package/packages/pegboard/src/workflows/actor/runtime.rs +909 -0
  700. package/packages/pegboard/src/workflows/actor/setup.rs +175 -0
  701. package/packages/pegboard/src/workflows/mod.rs +2 -0
  702. package/packages/pegboard/src/workflows/runner.rs +1182 -0
  703. package/packages/pegboard-gateway/Cargo.toml +35 -0
  704. package/packages/pegboard-gateway/src/keepalive_task.rs +61 -0
  705. package/packages/pegboard-gateway/src/lib.rs +698 -0
  706. package/packages/pegboard-gateway/src/metrics.rs +14 -0
  707. package/packages/pegboard-gateway/src/ping_task.rs +23 -0
  708. package/packages/pegboard-gateway/src/shared_state.rs +588 -0
  709. package/packages/pegboard-gateway/src/tunnel_to_ws_task.rs +85 -0
  710. package/packages/pegboard-gateway/src/ws_to_tunnel_task.rs +65 -0
  711. package/packages/pegboard-runner/Cargo.toml +38 -0
  712. package/packages/pegboard-runner/src/conn.rs +183 -0
  713. package/packages/pegboard-runner/src/errors.rs +33 -0
  714. package/packages/pegboard-runner/src/lib.rs +249 -0
  715. package/packages/pegboard-runner/src/ping_task.rs +66 -0
  716. package/packages/pegboard-runner/src/tunnel_to_ws_task.rs +137 -0
  717. package/packages/pegboard-runner/src/utils.rs +40 -0
  718. package/packages/pegboard-runner/src/ws_to_tunnel_task.rs +443 -0
  719. package/packages/pegboard-serverless/Cargo.toml +25 -0
  720. package/packages/pegboard-serverless/src/lib.rs +523 -0
  721. package/packages/pools/Cargo.toml +38 -0
  722. package/packages/pools/src/db/clickhouse.rs +37 -0
  723. package/packages/pools/src/db/mod.rs +3 -0
  724. package/packages/pools/src/db/udb.rs +37 -0
  725. package/packages/pools/src/db/ups.rs +91 -0
  726. package/packages/pools/src/error.rs +41 -0
  727. package/packages/pools/src/lib.rs +16 -0
  728. package/packages/pools/src/metrics.rs +32 -0
  729. package/packages/pools/src/pools.rs +114 -0
  730. package/packages/pools/src/prelude.rs +3 -0
  731. package/packages/pools/src/reqwest.rs +25 -0
  732. package/packages/runtime/Cargo.lock +1394 -0
  733. package/packages/runtime/Cargo.toml +29 -0
  734. package/packages/runtime/src/lib.rs +154 -0
  735. package/packages/runtime/src/metrics.rs +34 -0
  736. package/packages/runtime/src/term_signal.rs +113 -0
  737. package/packages/runtime/src/traces.rs +158 -0
  738. package/packages/service-manager/Cargo.toml +19 -0
  739. package/packages/service-manager/src/lib.rs +359 -0
  740. package/packages/telemetry/Cargo.toml +13 -0
  741. package/packages/telemetry/README.md +12 -0
  742. package/packages/telemetry/src/lib.rs +39 -0
  743. package/packages/test-deps/Cargo.toml +19 -0
  744. package/packages/test-deps/src/datacenter.rs +109 -0
  745. package/packages/test-deps/src/lib.rs +131 -0
  746. package/packages/test-deps-docker/Cargo.toml +14 -0
  747. package/packages/test-deps-docker/src/database.rs +135 -0
  748. package/packages/test-deps-docker/src/lib.rs +280 -0
  749. package/packages/test-deps-docker/src/pubsub.rs +76 -0
  750. package/packages/tracing-reconfigure/Cargo.toml +18 -0
  751. package/packages/tracing-reconfigure/src/lib.rs +78 -0
  752. package/packages/tracing-utils/Cargo.toml +12 -0
  753. package/packages/tracing-utils/src/lib.rs +91 -0
  754. package/packages/types/Cargo.toml +19 -0
  755. package/packages/types/README.md +3 -0
  756. package/packages/types/src/actors.rs +79 -0
  757. package/packages/types/src/datacenters.rs +10 -0
  758. package/packages/types/src/keys/mod.rs +2 -0
  759. package/packages/types/src/keys/namespace/mod.rs +1 -0
  760. package/packages/types/src/keys/namespace/runner_config.rs +28 -0
  761. package/packages/types/src/keys/pegboard/mod.rs +7 -0
  762. package/packages/types/src/keys/pegboard/ns.rs +109 -0
  763. package/packages/types/src/lib.rs +7 -0
  764. package/packages/types/src/msgs/mod.rs +1 -0
  765. package/packages/types/src/msgs/pegboard.rs +5 -0
  766. package/packages/types/src/namespaces.rs +10 -0
  767. package/packages/types/src/runner_configs.rs +96 -0
  768. package/packages/types/src/runners.rs +24 -0
  769. package/packages/universaldb/Cargo.toml +32 -0
  770. package/packages/universaldb/src/atomic.rs +190 -0
  771. package/packages/universaldb/src/database.rs +56 -0
  772. package/packages/universaldb/src/driver/mod.rs +87 -0
  773. package/packages/universaldb/src/driver/postgres/database.rs +244 -0
  774. package/packages/universaldb/src/driver/postgres/mod.rs +5 -0
  775. package/packages/universaldb/src/driver/postgres/transaction.rs +337 -0
  776. package/packages/universaldb/src/driver/postgres/transaction_task.rs +538 -0
  777. package/packages/universaldb/src/driver/rocksdb/database.rs +129 -0
  778. package/packages/universaldb/src/driver/rocksdb/mod.rs +6 -0
  779. package/packages/universaldb/src/driver/rocksdb/transaction.rs +354 -0
  780. package/packages/universaldb/src/driver/rocksdb/transaction_conflict_tracker.rs +109 -0
  781. package/packages/universaldb/src/driver/rocksdb/transaction_task.rs +526 -0
  782. package/packages/universaldb/src/error.rs +30 -0
  783. package/packages/universaldb/src/key_selector.rs +97 -0
  784. package/packages/universaldb/src/lib.rs +24 -0
  785. package/packages/universaldb/src/metrics.rs +27 -0
  786. package/packages/universaldb/src/options.rs +284 -0
  787. package/packages/universaldb/src/prelude.rs +8 -0
  788. package/packages/universaldb/src/range_option.rs +159 -0
  789. package/packages/universaldb/src/transaction.rs +378 -0
  790. package/packages/universaldb/src/tx_ops.rs +425 -0
  791. package/packages/universaldb/src/utils/cherry_pick.rs +88 -0
  792. package/packages/universaldb/src/utils/codes.rs +9 -0
  793. package/packages/universaldb/src/utils/ext.rs +58 -0
  794. package/packages/universaldb/src/utils/formal_key.rs +23 -0
  795. package/packages/universaldb/src/utils/keys.rs +134 -0
  796. package/packages/universaldb/src/utils/mod.rs +92 -0
  797. package/packages/universaldb/src/utils/subspace.rs +95 -0
  798. package/packages/universaldb/src/value.rs +159 -0
  799. package/packages/universaldb/src/versionstamp.rs +173 -0
  800. package/packages/universaldb/tests/integration.rs +2733 -0
  801. package/packages/universaldb/tests/integration_gas.rs +264 -0
  802. package/packages/universaldb/tests/rocksdb.rs +141 -0
  803. package/packages/universaldb/tests/versionstamp.rs +184 -0
  804. package/packages/universalpubsub/Cargo.toml +38 -0
  805. package/packages/universalpubsub/benches/simple.rs +932 -0
  806. package/packages/universalpubsub/src/chunking.rs +226 -0
  807. package/packages/universalpubsub/src/driver/memory/mod.rs +91 -0
  808. package/packages/universalpubsub/src/driver/mod.rs +58 -0
  809. package/packages/universalpubsub/src/driver/nats/mod.rs +79 -0
  810. package/packages/universalpubsub/src/driver/postgres/mod.rs +443 -0
  811. package/packages/universalpubsub/src/errors.rs +11 -0
  812. package/packages/universalpubsub/src/lib.rs +7 -0
  813. package/packages/universalpubsub/src/pubsub.rs +415 -0
  814. package/packages/universalpubsub/tests/integration.rs +441 -0
  815. package/packages/universalpubsub/tests/reconnect.rs +359 -0
  816. package/packages/util/Cargo.toml +41 -0
  817. package/packages/util/build.rs +13 -0
  818. package/packages/util/src/backoff.rs +109 -0
  819. package/packages/util/src/billing.rs +3 -0
  820. package/packages/util/src/build_meta.rs +33 -0
  821. package/packages/util/src/check.rs +222 -0
  822. package/packages/util/src/duration.rs +77 -0
  823. package/packages/util/src/faker.rs +81 -0
  824. package/packages/util/src/format.rs +185 -0
  825. package/packages/util/src/future.rs +1 -0
  826. package/packages/util/src/geo.rs +5 -0
  827. package/packages/util/src/lib.rs +40 -0
  828. package/packages/util/src/math.rs +35 -0
  829. package/packages/util/src/req.rs +41 -0
  830. package/packages/util/src/serde.rs +516 -0
  831. package/packages/util/src/size.rs +27 -0
  832. package/packages/util/src/sort.rs +13 -0
  833. package/packages/util/src/timestamp.rs +58 -0
  834. package/packages/util/src/url.rs +3 -0
  835. package/packages/util-id/Cargo.toml +13 -0
  836. package/packages/util-id/src/lib.rs +329 -0
  837. package/packages/workflow-worker/Cargo.toml +16 -0
  838. package/packages/workflow-worker/src/lib.rs +15 -0
  839. package/sdks/api/fern/fern.config.json +4 -0
  840. package/sdks/api/fern/generators.yml +25 -0
  841. package/sdks/go/api-full/client/client.go +459 -0
  842. package/sdks/go/api-full/client/client_test.go +43 -0
  843. package/sdks/go/api-full/client/options.go +39 -0
  844. package/sdks/go/api-full/core/client_option.go +44 -0
  845. package/sdks/go/api-full/core/core.go +220 -0
  846. package/sdks/go/api-full/core/core_test.go +219 -0
  847. package/sdks/go/api-full/core/stringer.go +13 -0
  848. package/sdks/go/api-full/datacenters/client.go +50 -0
  849. package/sdks/go/api-full/go.mod +8 -0
  850. package/sdks/go/api-full/go.sum +12 -0
  851. package/sdks/go/api-full/health/client.go +50 -0
  852. package/sdks/go/api-full/namespaces/client.go +92 -0
  853. package/sdks/go/api-full/namespaces.go +15 -0
  854. package/sdks/go/api-full/pointer.go +103 -0
  855. package/sdks/go/api-full/runners/client.go +111 -0
  856. package/sdks/go/api-full/runners.go +18 -0
  857. package/sdks/go/api-full/types.go +1638 -0
  858. package/sdks/rust/api-full/.openapi-generator/FILES +28 -0
  859. package/sdks/rust/api-full/.openapi-generator/VERSION +1 -0
  860. package/sdks/rust/api-full/.openapi-generator-ignore +23 -0
  861. package/sdks/rust/api-full/.travis.yml +1 -0
  862. package/sdks/rust/api-full/Cargo.toml +15 -0
  863. package/sdks/rust/api-full/README.md +53 -0
  864. package/sdks/rust/api-full/docs/Actor.md +19 -0
  865. package/sdks/rust/api-full/docs/ActorLifecycle.md +12 -0
  866. package/sdks/rust/api-full/docs/ActorsApi.md +37 -0
  867. package/sdks/rust/api-full/docs/ActorsCreateRequest.md +13 -0
  868. package/sdks/rust/api-full/docs/ActorsCreateResponse.md +11 -0
  869. package/sdks/rust/api-full/docs/Namespace.md +14 -0
  870. package/sdks/rust/api-full/docs/NamespacesCreateRequest.md +12 -0
  871. package/sdks/rust/api-full/docs/NamespacesCreateResponse.md +11 -0
  872. package/sdks/rust/api-full/docs/NsApi.md +37 -0
  873. package/sdks/rust/api-full/git_push.sh +57 -0
  874. package/sdks/rust/api-full/rust/.openapi-generator/FILES +140 -0
  875. package/sdks/rust/api-full/rust/.openapi-generator/VERSION +1 -0
  876. package/sdks/rust/api-full/rust/.openapi-generator-ignore +23 -0
  877. package/sdks/rust/api-full/rust/.travis.yml +1 -0
  878. package/sdks/rust/api-full/rust/Cargo.toml +15 -0
  879. package/sdks/rust/api-full/rust/README.md +111 -0
  880. package/sdks/rust/api-full/rust/docs/Actor.md +24 -0
  881. package/sdks/rust/api-full/rust/docs/ActorName.md +11 -0
  882. package/sdks/rust/api-full/rust/docs/ActorsCreateApi.md +40 -0
  883. package/sdks/rust/api-full/rust/docs/ActorsCreateRequest.md +16 -0
  884. package/sdks/rust/api-full/rust/docs/ActorsCreateResponse.md +11 -0
  885. package/sdks/rust/api-full/rust/docs/ActorsDeleteApi.md +40 -0
  886. package/sdks/rust/api-full/rust/docs/ActorsGetOrCreateApi.md +40 -0
  887. package/sdks/rust/api-full/rust/docs/ActorsGetOrCreateRequest.md +16 -0
  888. package/sdks/rust/api-full/rust/docs/ActorsGetOrCreateResponse.md +12 -0
  889. package/sdks/rust/api-full/rust/docs/ActorsKvGetApi.md +38 -0
  890. package/sdks/rust/api-full/rust/docs/ActorsKvGetResponse.md +12 -0
  891. package/sdks/rust/api-full/rust/docs/ActorsListApi.md +45 -0
  892. package/sdks/rust/api-full/rust/docs/ActorsListNamesApi.md +41 -0
  893. package/sdks/rust/api-full/rust/docs/ActorsListNamesResponse.md +12 -0
  894. package/sdks/rust/api-full/rust/docs/ActorsListResponse.md +12 -0
  895. package/sdks/rust/api-full/rust/docs/CrashPolicy.md +14 -0
  896. package/sdks/rust/api-full/rust/docs/Datacenter.md +13 -0
  897. package/sdks/rust/api-full/rust/docs/DatacenterHealth.md +16 -0
  898. package/sdks/rust/api-full/rust/docs/DatacentersApi.md +34 -0
  899. package/sdks/rust/api-full/rust/docs/DatacentersListResponse.md +12 -0
  900. package/sdks/rust/api-full/rust/docs/HealthApi.md +34 -0
  901. package/sdks/rust/api-full/rust/docs/HealthFanoutResponse.md +11 -0
  902. package/sdks/rust/api-full/rust/docs/HealthResponse.md +13 -0
  903. package/sdks/rust/api-full/rust/docs/HealthStatus.md +13 -0
  904. package/sdks/rust/api-full/rust/docs/Namespace.md +14 -0
  905. package/sdks/rust/api-full/rust/docs/NamespaceListResponse.md +12 -0
  906. package/sdks/rust/api-full/rust/docs/NamespacesApi.md +69 -0
  907. package/sdks/rust/api-full/rust/docs/NamespacesCreateRequest.md +12 -0
  908. package/sdks/rust/api-full/rust/docs/NamespacesCreateResponse.md +11 -0
  909. package/sdks/rust/api-full/rust/docs/Pagination.md +11 -0
  910. package/sdks/rust/api-full/rust/docs/Runner.md +25 -0
  911. package/sdks/rust/api-full/rust/docs/RunnerConfig.md +13 -0
  912. package/sdks/rust/api-full/rust/docs/RunnerConfigKind.md +12 -0
  913. package/sdks/rust/api-full/rust/docs/RunnerConfigKindOneOf.md +11 -0
  914. package/sdks/rust/api-full/rust/docs/RunnerConfigKindOneOf1.md +11 -0
  915. package/sdks/rust/api-full/rust/docs/RunnerConfigKindOneOf1Serverless.md +17 -0
  916. package/sdks/rust/api-full/rust/docs/RunnerConfigVariant.md +13 -0
  917. package/sdks/rust/api-full/rust/docs/RunnerConfigsDeleteApi.md +38 -0
  918. package/sdks/rust/api-full/rust/docs/RunnerConfigsListApi.md +41 -0
  919. package/sdks/rust/api-full/rust/docs/RunnerConfigsListResponse.md +12 -0
  920. package/sdks/rust/api-full/rust/docs/RunnerConfigsListResponseRunnerConfigsValue.md +11 -0
  921. package/sdks/rust/api-full/rust/docs/RunnerConfigsRefreshMetadataApi.md +39 -0
  922. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckApi.md +38 -0
  923. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckRequest.md +12 -0
  924. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponse.md +12 -0
  925. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOf.md +11 -0
  926. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOf1.md +11 -0
  927. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOf1Failure.md +11 -0
  928. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessHealthCheckResponseOneOfSuccess.md +11 -0
  929. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataError.md +16 -0
  930. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf.md +11 -0
  931. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf1.md +11 -0
  932. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf2.md +11 -0
  933. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf3.md +11 -0
  934. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf3NonSuccessStatus.md +12 -0
  935. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf4.md +11 -0
  936. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf4InvalidResponseJson.md +11 -0
  937. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf5.md +11 -0
  938. package/sdks/rust/api-full/rust/docs/RunnerConfigsServerlessMetadataErrorOneOf5InvalidResponseSchema.md +12 -0
  939. package/sdks/rust/api-full/rust/docs/RunnerConfigsUpsertApi.md +39 -0
  940. package/sdks/rust/api-full/rust/docs/RunnerConfigsUpsertRequestBody.md +11 -0
  941. package/sdks/rust/api-full/rust/docs/RunnerConfigsUpsertResponse.md +11 -0
  942. package/sdks/rust/api-full/rust/docs/RunnersApi.md +75 -0
  943. package/sdks/rust/api-full/rust/docs/RunnersListNamesResponse.md +12 -0
  944. package/sdks/rust/api-full/rust/docs/RunnersListResponse.md +12 -0
  945. package/sdks/rust/api-full/rust/git_push.sh +57 -0
  946. package/sdks/rust/api-full/rust/src/apis/actors_create_api.rs +68 -0
  947. package/sdks/rust/api-full/rust/src/apis/actors_delete_api.rs +69 -0
  948. package/sdks/rust/api-full/rust/src/apis/actors_get_or_create_api.rs +68 -0
  949. package/sdks/rust/api-full/rust/src/apis/actors_kv_get_api.rs +65 -0
  950. package/sdks/rust/api-full/rust/src/apis/actors_list_api.rs +90 -0
  951. package/sdks/rust/api-full/rust/src/apis/actors_list_names_api.rs +74 -0
  952. package/sdks/rust/api-full/rust/src/apis/configuration.rs +51 -0
  953. package/sdks/rust/api-full/rust/src/apis/datacenters_api.rs +62 -0
  954. package/sdks/rust/api-full/rust/src/apis/health_api.rs +62 -0
  955. package/sdks/rust/api-full/rust/src/apis/mod.rs +130 -0
  956. package/sdks/rust/api-full/rust/src/apis/namespaces_api.rs +126 -0
  957. package/sdks/rust/api-full/rust/src/apis/runner_configs_delete_api.rs +66 -0
  958. package/sdks/rust/api-full/rust/src/apis/runner_configs_list_api.rs +81 -0
  959. package/sdks/rust/api-full/rust/src/apis/runner_configs_refresh_metadata_api.rs +68 -0
  960. package/sdks/rust/api-full/rust/src/apis/runner_configs_serverless_health_check_api.rs +67 -0
  961. package/sdks/rust/api-full/rust/src/apis/runner_configs_upsert_api.rs +68 -0
  962. package/sdks/rust/api-full/rust/src/apis/runners_api.rs +141 -0
  963. package/sdks/rust/api-full/rust/src/lib.rs +11 -0
  964. package/sdks/rust/api-full/rust/src/models/actor.rs +73 -0
  965. package/sdks/rust/api-full/rust/src/models/actor_name.rs +27 -0
  966. package/sdks/rust/api-full/rust/src/models/actors_create_request.rs +42 -0
  967. package/sdks/rust/api-full/rust/src/models/actors_create_response.rs +27 -0
  968. package/sdks/rust/api-full/rust/src/models/actors_get_or_create_request.rs +42 -0
  969. package/sdks/rust/api-full/rust/src/models/actors_get_or_create_response.rs +30 -0
  970. package/sdks/rust/api-full/rust/src/models/actors_kv_get_response.rs +30 -0
  971. package/sdks/rust/api-full/rust/src/models/actors_list_names_response.rs +30 -0
  972. package/sdks/rust/api-full/rust/src/models/actors_list_response.rs +30 -0
  973. package/sdks/rust/api-full/rust/src/models/crash_policy.rs +41 -0
  974. package/sdks/rust/api-full/rust/src/models/datacenter.rs +33 -0
  975. package/sdks/rust/api-full/rust/src/models/datacenter_health.rs +42 -0
  976. package/sdks/rust/api-full/rust/src/models/datacenters_list_response.rs +30 -0
  977. package/sdks/rust/api-full/rust/src/models/health_fanout_response.rs +27 -0
  978. package/sdks/rust/api-full/rust/src/models/health_response.rs +33 -0
  979. package/sdks/rust/api-full/rust/src/models/health_status.rs +38 -0
  980. package/sdks/rust/api-full/rust/src/models/mod.rs +100 -0
  981. package/sdks/rust/api-full/rust/src/models/namespace.rs +36 -0
  982. package/sdks/rust/api-full/rust/src/models/namespace_list_response.rs +30 -0
  983. package/sdks/rust/api-full/rust/src/models/namespaces_create_request.rs +30 -0
  984. package/sdks/rust/api-full/rust/src/models/namespaces_create_response.rs +27 -0
  985. package/sdks/rust/api-full/rust/src/models/pagination.rs +27 -0
  986. package/sdks/rust/api-full/rust/src/models/runner.rs +69 -0
  987. package/sdks/rust/api-full/rust/src/models/runner_config.rs +33 -0
  988. package/sdks/rust/api-full/rust/src/models/runner_config_kind.rs +26 -0
  989. package/sdks/rust/api-full/rust/src/models/runner_config_kind_one_of.rs +27 -0
  990. package/sdks/rust/api-full/rust/src/models/runner_config_kind_one_of_1.rs +27 -0
  991. package/sdks/rust/api-full/rust/src/models/runner_config_kind_one_of_1_serverless.rs +46 -0
  992. package/sdks/rust/api-full/rust/src/models/runner_config_variant.rs +38 -0
  993. package/sdks/rust/api-full/rust/src/models/runner_configs_list_response.rs +30 -0
  994. package/sdks/rust/api-full/rust/src/models/runner_configs_list_response_runner_configs_value.rs +27 -0
  995. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_request.rs +30 -0
  996. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response.rs +26 -0
  997. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of.rs +27 -0
  998. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of_1.rs +27 -0
  999. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of_1_failure.rs +27 -0
  1000. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_health_check_response_one_of_success.rs +27 -0
  1001. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error.rs +30 -0
  1002. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of.rs +27 -0
  1003. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_1.rs +27 -0
  1004. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_2.rs +27 -0
  1005. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_3.rs +27 -0
  1006. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_3_non_success_status.rs +30 -0
  1007. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_4.rs +27 -0
  1008. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_4_invalid_response_json.rs +27 -0
  1009. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_5.rs +27 -0
  1010. package/sdks/rust/api-full/rust/src/models/runner_configs_serverless_metadata_error_one_of_5_invalid_response_schema.rs +30 -0
  1011. package/sdks/rust/api-full/rust/src/models/runner_configs_upsert_request_body.rs +27 -0
  1012. package/sdks/rust/api-full/rust/src/models/runner_configs_upsert_response.rs +27 -0
  1013. package/sdks/rust/api-full/rust/src/models/runners_list_names_response.rs +30 -0
  1014. package/sdks/rust/api-full/rust/src/models/runners_list_response.rs +30 -0
  1015. package/sdks/rust/api-full/src/apis/actors_api.rs +67 -0
  1016. package/sdks/rust/api-full/src/apis/configuration.rs +48 -0
  1017. package/sdks/rust/api-full/src/apis/mod.rs +119 -0
  1018. package/sdks/rust/api-full/src/apis/ns_api.rs +67 -0
  1019. package/sdks/rust/api-full/src/lib.rs +11 -0
  1020. package/sdks/rust/api-full/src/models/actor.rs +72 -0
  1021. package/sdks/rust/api-full/src/models/actor_lifecycle.rs +29 -0
  1022. package/sdks/rust/api-full/src/models/actors_create_request.rs +36 -0
  1023. package/sdks/rust/api-full/src/models/actors_create_response.rs +26 -0
  1024. package/sdks/rust/api-full/src/models/mod.rs +14 -0
  1025. package/sdks/rust/api-full/src/models/namespace.rs +40 -0
  1026. package/sdks/rust/api-full/src/models/namespaces_create_request.rs +26 -0
  1027. package/sdks/rust/api-full/src/models/namespaces_create_response.rs +26 -0
  1028. package/sdks/rust/data/Cargo.toml +18 -0
  1029. package/sdks/rust/data/build.rs +15 -0
  1030. package/sdks/rust/data/src/converted.rs +137 -0
  1031. package/sdks/rust/data/src/generated.rs +1 -0
  1032. package/sdks/rust/data/src/lib.rs +11 -0
  1033. package/sdks/rust/data/src/versioned/mod.rs +178 -0
  1034. package/sdks/rust/data/src/versioned/namespace_runner_config.rs +125 -0
  1035. package/sdks/rust/epoxy-protocol/Cargo.toml +17 -0
  1036. package/sdks/rust/epoxy-protocol/build.rs +18 -0
  1037. package/sdks/rust/epoxy-protocol/src/generated.rs +1 -0
  1038. package/sdks/rust/epoxy-protocol/src/lib.rs +7 -0
  1039. package/sdks/rust/epoxy-protocol/src/versioned.rs +206 -0
  1040. package/sdks/rust/runner-protocol/Cargo.toml +23 -0
  1041. package/sdks/rust/runner-protocol/build.rs +115 -0
  1042. package/sdks/rust/runner-protocol/src/compat.rs +7 -0
  1043. package/sdks/rust/runner-protocol/src/generated.rs +1 -0
  1044. package/sdks/rust/runner-protocol/src/lib.rs +10 -0
  1045. package/sdks/rust/runner-protocol/src/util.rs +14 -0
  1046. package/sdks/rust/runner-protocol/src/uuid_compat.rs +209 -0
  1047. package/sdks/rust/runner-protocol/src/versioned.rs +1734 -0
  1048. package/sdks/rust/ups-protocol/Cargo.toml +17 -0
  1049. package/sdks/rust/ups-protocol/build.rs +18 -0
  1050. package/sdks/rust/ups-protocol/src/generated.rs +1 -0
  1051. package/sdks/rust/ups-protocol/src/lib.rs +7 -0
  1052. package/sdks/rust/ups-protocol/src/versioned.rs +48 -0
  1053. package/sdks/schemas/README.md +6 -0
  1054. package/sdks/schemas/data/namespace.runner_config.v1.bare +13 -0
  1055. package/sdks/schemas/data/namespace.runner_config.v2.bare +23 -0
  1056. package/sdks/schemas/data/pegboard.namespace.actor_by_key.v1.bare +6 -0
  1057. package/sdks/schemas/data/pegboard.namespace.actor_name.v1.bare +5 -0
  1058. package/sdks/schemas/data/pegboard.namespace.runner_alloc_idx.v1.bare +7 -0
  1059. package/sdks/schemas/data/pegboard.namespace.runner_by_key.v1.bare +6 -0
  1060. package/sdks/schemas/data/pegboard.runner.metadata.v1.bare +5 -0
  1061. package/sdks/schemas/epoxy-protocol/v1.bare +260 -0
  1062. package/sdks/schemas/runner-protocol/v1.bare +393 -0
  1063. package/sdks/schemas/runner-protocol/v2.bare +403 -0
  1064. package/sdks/schemas/runner-protocol/v3.bare +436 -0
  1065. package/sdks/schemas/ups-protocol/v1.bare +23 -0
  1066. package/sdks/typescript/api-full/.turbo/turbo-build.log +42 -0
  1067. package/sdks/typescript/api-full/build.js +69 -0
  1068. package/sdks/typescript/api-full/package.json +59 -0
  1069. package/sdks/typescript/api-full/rivetkit-engine-api-full-25.5.3.tgz +0 -0
  1070. package/sdks/typescript/api-full/src/Client.ts +984 -0
  1071. package/sdks/typescript/api-full/src/api/client/index.ts +1 -0
  1072. package/sdks/typescript/api-full/src/api/client/requests/ActorsCreateRequest.ts +24 -0
  1073. package/sdks/typescript/api-full/src/api/client/requests/ActorsDeleteRequest.ts +11 -0
  1074. package/sdks/typescript/api-full/src/api/client/requests/ActorsGetOrCreateRequest.ts +25 -0
  1075. package/sdks/typescript/api-full/src/api/client/requests/ActorsListNamesRequest.ts +15 -0
  1076. package/sdks/typescript/api-full/src/api/client/requests/ActorsListRequest.ts +19 -0
  1077. package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsDeleteRequest.ts +13 -0
  1078. package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsListRequest.ts +19 -0
  1079. package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsRefreshMetadataRequest.ts +19 -0
  1080. package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts +16 -0
  1081. package/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsUpsertRequestBody.ts +19 -0
  1082. package/sdks/typescript/api-full/src/api/client/requests/index.ts +10 -0
  1083. package/sdks/typescript/api-full/src/api/index.ts +3 -0
  1084. package/sdks/typescript/api-full/src/api/resources/datacenters/client/Client.ts +97 -0
  1085. package/sdks/typescript/api-full/src/api/resources/datacenters/client/index.ts +1 -0
  1086. package/sdks/typescript/api-full/src/api/resources/datacenters/index.ts +1 -0
  1087. package/sdks/typescript/api-full/src/api/resources/health/client/Client.ts +97 -0
  1088. package/sdks/typescript/api-full/src/api/resources/health/client/index.ts +1 -0
  1089. package/sdks/typescript/api-full/src/api/resources/health/index.ts +1 -0
  1090. package/sdks/typescript/api-full/src/api/resources/index.ts +6 -0
  1091. package/sdks/typescript/api-full/src/api/resources/namespaces/client/Client.ts +187 -0
  1092. package/sdks/typescript/api-full/src/api/resources/namespaces/client/index.ts +1 -0
  1093. package/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesCreateRequest.ts +15 -0
  1094. package/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesListRequest.ts +14 -0
  1095. package/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/index.ts +2 -0
  1096. package/sdks/typescript/api-full/src/api/resources/namespaces/index.ts +1 -0
  1097. package/sdks/typescript/api-full/src/api/resources/runners/client/Client.ts +209 -0
  1098. package/sdks/typescript/api-full/src/api/resources/runners/client/index.ts +1 -0
  1099. package/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListNamesRequest.ts +15 -0
  1100. package/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListRequest.ts +18 -0
  1101. package/sdks/typescript/api-full/src/api/resources/runners/client/requests/index.ts +2 -0
  1102. package/sdks/typescript/api-full/src/api/resources/runners/index.ts +1 -0
  1103. package/sdks/typescript/api-full/src/api/types/Actor.ts +32 -0
  1104. package/sdks/typescript/api-full/src/api/types/ActorName.ts +7 -0
  1105. package/sdks/typescript/api-full/src/api/types/ActorsCreateResponse.ts +9 -0
  1106. package/sdks/typescript/api-full/src/api/types/ActorsDeleteResponse.ts +5 -0
  1107. package/sdks/typescript/api-full/src/api/types/ActorsGetOrCreateResponse.ts +10 -0
  1108. package/sdks/typescript/api-full/src/api/types/ActorsKvGetResponse.ts +8 -0
  1109. package/sdks/typescript/api-full/src/api/types/ActorsListNamesResponse.ts +10 -0
  1110. package/sdks/typescript/api-full/src/api/types/ActorsListResponse.ts +10 -0
  1111. package/sdks/typescript/api-full/src/api/types/CrashPolicy.ts +10 -0
  1112. package/sdks/typescript/api-full/src/api/types/Datacenter.ts +9 -0
  1113. package/sdks/typescript/api-full/src/api/types/DatacenterHealth.ts +14 -0
  1114. package/sdks/typescript/api-full/src/api/types/DatacentersListResponse.ts +10 -0
  1115. package/sdks/typescript/api-full/src/api/types/HealthFanoutResponse.ts +9 -0
  1116. package/sdks/typescript/api-full/src/api/types/HealthResponse.ts +9 -0
  1117. package/sdks/typescript/api-full/src/api/types/HealthStatus.ts +9 -0
  1118. package/sdks/typescript/api-full/src/api/types/Namespace.ts +12 -0
  1119. package/sdks/typescript/api-full/src/api/types/NamespaceListResponse.ts +10 -0
  1120. package/sdks/typescript/api-full/src/api/types/NamespacesCreateResponse.ts +9 -0
  1121. package/sdks/typescript/api-full/src/api/types/Pagination.ts +7 -0
  1122. package/sdks/typescript/api-full/src/api/types/RivetId.ts +5 -0
  1123. package/sdks/typescript/api-full/src/api/types/Runner.ts +23 -0
  1124. package/sdks/typescript/api-full/src/api/types/RunnerConfig.ts +11 -0
  1125. package/sdks/typescript/api-full/src/api/types/RunnerConfigKind.ts +7 -0
  1126. package/sdks/typescript/api-full/src/api/types/RunnerConfigKindNormal.ts +7 -0
  1127. package/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerless.ts +9 -0
  1128. package/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerlessServerless.ts +14 -0
  1129. package/sdks/typescript/api-full/src/api/types/RunnerConfigServerless.ts +14 -0
  1130. package/sdks/typescript/api-full/src/api/types/RunnerConfigVariant.ts +9 -0
  1131. package/sdks/typescript/api-full/src/api/types/RunnerConfigsDeleteResponse.ts +5 -0
  1132. package/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponse.ts +10 -0
  1133. package/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponseRunnerConfigsValue.ts +9 -0
  1134. package/sdks/typescript/api-full/src/api/types/RunnerConfigsRefreshMetadataRequestBody.ts +5 -0
  1135. package/sdks/typescript/api-full/src/api/types/RunnerConfigsRefreshMetadataResponse.ts +5 -0
  1136. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponse.ts +9 -0
  1137. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts +9 -0
  1138. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts +9 -0
  1139. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts +9 -0
  1140. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts +7 -0
  1141. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataError.ts +13 -0
  1142. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts +7 -0
  1143. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts +9 -0
  1144. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts +7 -0
  1145. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts +9 -0
  1146. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts +8 -0
  1147. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts +9 -0
  1148. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts +8 -0
  1149. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts +7 -0
  1150. package/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts +7 -0
  1151. package/sdks/typescript/api-full/src/api/types/RunnerConfigsUpsertResponse.ts +7 -0
  1152. package/sdks/typescript/api-full/src/api/types/RunnersListNamesResponse.ts +10 -0
  1153. package/sdks/typescript/api-full/src/api/types/RunnersListResponse.ts +10 -0
  1154. package/sdks/typescript/api-full/src/api/types/index.ts +51 -0
  1155. package/sdks/typescript/api-full/src/core/auth/BasicAuth.ts +31 -0
  1156. package/sdks/typescript/api-full/src/core/auth/BearerToken.ts +15 -0
  1157. package/sdks/typescript/api-full/src/core/auth/index.ts +2 -0
  1158. package/sdks/typescript/api-full/src/core/fetcher/APIResponse.ts +12 -0
  1159. package/sdks/typescript/api-full/src/core/fetcher/Fetcher.ts +144 -0
  1160. package/sdks/typescript/api-full/src/core/fetcher/Supplier.ts +11 -0
  1161. package/sdks/typescript/api-full/src/core/fetcher/createRequestUrl.ts +10 -0
  1162. package/sdks/typescript/api-full/src/core/fetcher/getFetchFn.ts +25 -0
  1163. package/sdks/typescript/api-full/src/core/fetcher/getHeader.ts +8 -0
  1164. package/sdks/typescript/api-full/src/core/fetcher/getRequestBody.ts +16 -0
  1165. package/sdks/typescript/api-full/src/core/fetcher/getResponseBody.ts +34 -0
  1166. package/sdks/typescript/api-full/src/core/fetcher/index.ts +5 -0
  1167. package/sdks/typescript/api-full/src/core/fetcher/makeRequest.ts +44 -0
  1168. package/sdks/typescript/api-full/src/core/fetcher/requestWithRetries.ts +33 -0
  1169. package/sdks/typescript/api-full/src/core/fetcher/signals.ts +38 -0
  1170. package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts +257 -0
  1171. package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts +107 -0
  1172. package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts +243 -0
  1173. package/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/chooseStreamWrapper.ts +34 -0
  1174. package/sdks/typescript/api-full/src/core/index.ts +4 -0
  1175. package/sdks/typescript/api-full/src/core/json.ts +27 -0
  1176. package/sdks/typescript/api-full/src/core/runtime/index.ts +1 -0
  1177. package/sdks/typescript/api-full/src/core/runtime/runtime.ts +131 -0
  1178. package/sdks/typescript/api-full/src/core/schemas/Schema.ts +101 -0
  1179. package/sdks/typescript/api-full/src/core/schemas/builders/bigint/bigint.ts +55 -0
  1180. package/sdks/typescript/api-full/src/core/schemas/builders/bigint/index.ts +1 -0
  1181. package/sdks/typescript/api-full/src/core/schemas/builders/date/date.ts +65 -0
  1182. package/sdks/typescript/api-full/src/core/schemas/builders/date/index.ts +1 -0
  1183. package/sdks/typescript/api-full/src/core/schemas/builders/enum/enum.ts +43 -0
  1184. package/sdks/typescript/api-full/src/core/schemas/builders/enum/index.ts +1 -0
  1185. package/sdks/typescript/api-full/src/core/schemas/builders/index.ts +14 -0
  1186. package/sdks/typescript/api-full/src/core/schemas/builders/lazy/index.ts +3 -0
  1187. package/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazy.ts +32 -0
  1188. package/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazyObject.ts +20 -0
  1189. package/sdks/typescript/api-full/src/core/schemas/builders/list/index.ts +1 -0
  1190. package/sdks/typescript/api-full/src/core/schemas/builders/list/list.ts +73 -0
  1191. package/sdks/typescript/api-full/src/core/schemas/builders/literals/booleanLiteral.ts +29 -0
  1192. package/sdks/typescript/api-full/src/core/schemas/builders/literals/index.ts +2 -0
  1193. package/sdks/typescript/api-full/src/core/schemas/builders/literals/stringLiteral.ts +29 -0
  1194. package/sdks/typescript/api-full/src/core/schemas/builders/object/index.ts +22 -0
  1195. package/sdks/typescript/api-full/src/core/schemas/builders/object/object.ts +366 -0
  1196. package/sdks/typescript/api-full/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts +18 -0
  1197. package/sdks/typescript/api-full/src/core/schemas/builders/object/property.ts +23 -0
  1198. package/sdks/typescript/api-full/src/core/schemas/builders/object/types.ts +58 -0
  1199. package/sdks/typescript/api-full/src/core/schemas/builders/object-like/getObjectLikeUtils.ts +79 -0
  1200. package/sdks/typescript/api-full/src/core/schemas/builders/object-like/index.ts +2 -0
  1201. package/sdks/typescript/api-full/src/core/schemas/builders/object-like/types.ts +11 -0
  1202. package/sdks/typescript/api-full/src/core/schemas/builders/primitives/any.ts +4 -0
  1203. package/sdks/typescript/api-full/src/core/schemas/builders/primitives/boolean.ts +25 -0
  1204. package/sdks/typescript/api-full/src/core/schemas/builders/primitives/index.ts +5 -0
  1205. package/sdks/typescript/api-full/src/core/schemas/builders/primitives/number.ts +25 -0
  1206. package/sdks/typescript/api-full/src/core/schemas/builders/primitives/string.ts +25 -0
  1207. package/sdks/typescript/api-full/src/core/schemas/builders/primitives/unknown.ts +4 -0
  1208. package/sdks/typescript/api-full/src/core/schemas/builders/record/index.ts +2 -0
  1209. package/sdks/typescript/api-full/src/core/schemas/builders/record/record.ts +129 -0
  1210. package/sdks/typescript/api-full/src/core/schemas/builders/record/types.ts +17 -0
  1211. package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/JsonError.ts +9 -0
  1212. package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/ParseError.ts +9 -0
  1213. package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/getSchemaUtils.ts +181 -0
  1214. package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/index.ts +4 -0
  1215. package/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts +8 -0
  1216. package/sdks/typescript/api-full/src/core/schemas/builders/set/index.ts +1 -0
  1217. package/sdks/typescript/api-full/src/core/schemas/builders/set/set.ts +43 -0
  1218. package/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/index.ts +6 -0
  1219. package/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/types.ts +10 -0
  1220. package/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts +60 -0
  1221. package/sdks/typescript/api-full/src/core/schemas/builders/union/discriminant.ts +14 -0
  1222. package/sdks/typescript/api-full/src/core/schemas/builders/union/index.ts +10 -0
  1223. package/sdks/typescript/api-full/src/core/schemas/builders/union/types.ts +26 -0
  1224. package/sdks/typescript/api-full/src/core/schemas/builders/union/union.ts +170 -0
  1225. package/sdks/typescript/api-full/src/core/schemas/index.ts +2 -0
  1226. package/sdks/typescript/api-full/src/core/schemas/utils/MaybePromise.ts +1 -0
  1227. package/sdks/typescript/api-full/src/core/schemas/utils/addQuestionMarksToNullableProperties.ts +9 -0
  1228. package/sdks/typescript/api-full/src/core/schemas/utils/createIdentitySchemaCreator.ts +21 -0
  1229. package/sdks/typescript/api-full/src/core/schemas/utils/entries.ts +3 -0
  1230. package/sdks/typescript/api-full/src/core/schemas/utils/filterObject.ts +13 -0
  1231. package/sdks/typescript/api-full/src/core/schemas/utils/getErrorMessageForIncorrectType.ts +25 -0
  1232. package/sdks/typescript/api-full/src/core/schemas/utils/isPlainObject.ts +17 -0
  1233. package/sdks/typescript/api-full/src/core/schemas/utils/keys.ts +3 -0
  1234. package/sdks/typescript/api-full/src/core/schemas/utils/maybeSkipValidation.ts +38 -0
  1235. package/sdks/typescript/api-full/src/core/schemas/utils/partition.ts +12 -0
  1236. package/sdks/typescript/api-full/src/errors/RivetError.ts +47 -0
  1237. package/sdks/typescript/api-full/src/errors/RivetTimeoutError.ts +10 -0
  1238. package/sdks/typescript/api-full/src/errors/index.ts +2 -0
  1239. package/sdks/typescript/api-full/src/index.ts +4 -0
  1240. package/sdks/typescript/api-full/src/serialization/client/index.ts +1 -0
  1241. package/sdks/typescript/api-full/src/serialization/client/requests/ActorsCreateRequest.ts +31 -0
  1242. package/sdks/typescript/api-full/src/serialization/client/requests/ActorsGetOrCreateRequest.ts +31 -0
  1243. package/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts +22 -0
  1244. package/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsUpsertRequestBody.ts +21 -0
  1245. package/sdks/typescript/api-full/src/serialization/client/requests/index.ts +4 -0
  1246. package/sdks/typescript/api-full/src/serialization/index.ts +3 -0
  1247. package/sdks/typescript/api-full/src/serialization/resources/index.ts +2 -0
  1248. package/sdks/typescript/api-full/src/serialization/resources/namespaces/client/index.ts +1 -0
  1249. package/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/NamespacesCreateRequest.ts +22 -0
  1250. package/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/index.ts +1 -0
  1251. package/sdks/typescript/api-full/src/serialization/resources/namespaces/index.ts +1 -0
  1252. package/sdks/typescript/api-full/src/serialization/types/Actor.ts +45 -0
  1253. package/sdks/typescript/api-full/src/serialization/types/ActorName.ts +18 -0
  1254. package/sdks/typescript/api-full/src/serialization/types/ActorsCreateResponse.ts +21 -0
  1255. package/sdks/typescript/api-full/src/serialization/types/ActorsDeleteResponse.ts +16 -0
  1256. package/sdks/typescript/api-full/src/serialization/types/ActorsGetOrCreateResponse.ts +23 -0
  1257. package/sdks/typescript/api-full/src/serialization/types/ActorsKvGetResponse.ts +22 -0
  1258. package/sdks/typescript/api-full/src/serialization/types/ActorsListNamesResponse.ts +24 -0
  1259. package/sdks/typescript/api-full/src/serialization/types/ActorsListResponse.ts +24 -0
  1260. package/sdks/typescript/api-full/src/serialization/types/CrashPolicy.ts +14 -0
  1261. package/sdks/typescript/api-full/src/serialization/types/Datacenter.ts +22 -0
  1262. package/sdks/typescript/api-full/src/serialization/types/DatacenterHealth.ts +32 -0
  1263. package/sdks/typescript/api-full/src/serialization/types/DatacentersListResponse.ts +24 -0
  1264. package/sdks/typescript/api-full/src/serialization/types/HealthFanoutResponse.ts +21 -0
  1265. package/sdks/typescript/api-full/src/serialization/types/HealthResponse.ts +22 -0
  1266. package/sdks/typescript/api-full/src/serialization/types/HealthStatus.ts +14 -0
  1267. package/sdks/typescript/api-full/src/serialization/types/Namespace.ts +25 -0
  1268. package/sdks/typescript/api-full/src/serialization/types/NamespaceListResponse.ts +24 -0
  1269. package/sdks/typescript/api-full/src/serialization/types/NamespacesCreateResponse.ts +21 -0
  1270. package/sdks/typescript/api-full/src/serialization/types/Pagination.ts +18 -0
  1271. package/sdks/typescript/api-full/src/serialization/types/RivetId.ts +13 -0
  1272. package/sdks/typescript/api-full/src/serialization/types/Runner.ts +46 -0
  1273. package/sdks/typescript/api-full/src/serialization/types/RunnerConfig.ts +23 -0
  1274. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKind.ts +16 -0
  1275. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindNormal.ts +20 -0
  1276. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerless.ts +21 -0
  1277. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerlessServerless.ts +32 -0
  1278. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigServerless.ts +32 -0
  1279. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigVariant.ts +16 -0
  1280. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsDeleteResponse.ts +16 -0
  1281. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponse.ts +27 -0
  1282. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponseRunnerConfigsValue.ts +21 -0
  1283. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataRequestBody.ts +16 -0
  1284. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataResponse.ts +16 -0
  1285. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponse.ts +23 -0
  1286. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts +21 -0
  1287. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts +21 -0
  1288. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts +21 -0
  1289. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts +20 -0
  1290. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataError.ts +35 -0
  1291. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts +23 -0
  1292. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts +24 -0
  1293. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts +20 -0
  1294. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts +24 -0
  1295. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts +22 -0
  1296. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts +24 -0
  1297. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts +22 -0
  1298. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts +23 -0
  1299. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts +23 -0
  1300. package/sdks/typescript/api-full/src/serialization/types/RunnerConfigsUpsertResponse.ts +20 -0
  1301. package/sdks/typescript/api-full/src/serialization/types/RunnersListNamesResponse.ts +23 -0
  1302. package/sdks/typescript/api-full/src/serialization/types/RunnersListResponse.ts +24 -0
  1303. package/sdks/typescript/api-full/src/serialization/types/index.ts +51 -0
  1304. package/sdks/typescript/api-full/tsconfig.json +24 -0
  1305. package/sdks/typescript/runner/.turbo/turbo-build.log +22 -0
  1306. package/sdks/typescript/runner/benches/actor-lifecycle.bench.ts +190 -0
  1307. package/sdks/typescript/runner/benches/utils.ts +143 -0
  1308. package/sdks/typescript/runner/dist/mod.cjs +2951 -0
  1309. package/sdks/typescript/runner/dist/mod.cjs.map +1 -0
  1310. package/sdks/typescript/runner/dist/mod.d.cts +326 -0
  1311. package/sdks/typescript/runner/dist/mod.d.ts +326 -0
  1312. package/sdks/typescript/runner/dist/mod.js +2951 -0
  1313. package/sdks/typescript/runner/dist/mod.js.map +1 -0
  1314. package/sdks/typescript/runner/node_modules/.bin/pino +21 -0
  1315. package/sdks/typescript/runner/node_modules/.bin/tsc +21 -0
  1316. package/sdks/typescript/runner/node_modules/.bin/tsserver +21 -0
  1317. package/sdks/typescript/runner/node_modules/.bin/tsup +21 -0
  1318. package/sdks/typescript/runner/node_modules/.bin/tsup-node +21 -0
  1319. package/sdks/typescript/runner/node_modules/.bin/tsx +21 -0
  1320. package/sdks/typescript/runner/node_modules/.bin/uuid +21 -0
  1321. package/sdks/typescript/runner/node_modules/.bin/vitest +21 -0
  1322. package/sdks/typescript/runner/package.json +37 -0
  1323. package/sdks/typescript/runner/src/actor.ts +196 -0
  1324. package/sdks/typescript/runner/src/log.ts +11 -0
  1325. package/sdks/typescript/runner/src/mod.ts +1755 -0
  1326. package/sdks/typescript/runner/src/stringify.ts +354 -0
  1327. package/sdks/typescript/runner/src/tunnel.ts +1178 -0
  1328. package/sdks/typescript/runner/src/utils.ts +159 -0
  1329. package/sdks/typescript/runner/src/websocket-tunnel-adapter.ts +567 -0
  1330. package/sdks/typescript/runner/src/websocket.ts +43 -0
  1331. package/sdks/typescript/runner/tests/lifecycle.test.ts +596 -0
  1332. package/sdks/typescript/runner/tests/utils.test.ts +194 -0
  1333. package/sdks/typescript/runner/tsconfig.json +11 -0
  1334. package/sdks/typescript/runner/tsup.config.ts +4 -0
  1335. package/sdks/typescript/runner/turbo.json +4 -0
  1336. package/sdks/typescript/runner/vitest.config.ts +16 -0
  1337. package/sdks/typescript/runner-protocol/.turbo/turbo-build.log +22 -0
  1338. package/sdks/typescript/runner-protocol/dist/index.cjs +1632 -0
  1339. package/sdks/typescript/runner-protocol/dist/index.cjs.map +1 -0
  1340. package/sdks/typescript/runner-protocol/dist/index.d.cts +666 -0
  1341. package/sdks/typescript/runner-protocol/dist/index.d.ts +666 -0
  1342. package/sdks/typescript/runner-protocol/dist/index.js +1632 -0
  1343. package/sdks/typescript/runner-protocol/dist/index.js.map +1 -0
  1344. package/sdks/typescript/runner-protocol/node_modules/.bin/tsc +21 -0
  1345. package/sdks/typescript/runner-protocol/node_modules/.bin/tsserver +21 -0
  1346. package/sdks/typescript/runner-protocol/node_modules/.bin/tsup +21 -0
  1347. package/sdks/typescript/runner-protocol/node_modules/.bin/tsup-node +21 -0
  1348. package/sdks/typescript/runner-protocol/package.json +34 -0
  1349. package/sdks/typescript/runner-protocol/src/index.ts +2121 -0
  1350. package/sdks/typescript/runner-protocol/tsconfig.json +17 -0
  1351. package/sdks/typescript/runner-protocol/tsup.config.ts +4 -0
  1352. package/sdks/typescript/runner-protocol/turbo.json +4 -0
  1353. package/sdks/typescript/test-runner/.turbo/turbo-build.log +17 -0
  1354. package/sdks/typescript/test-runner/Dockerfile +26 -0
  1355. package/sdks/typescript/test-runner/dist/index.d.ts +6 -0
  1356. package/sdks/typescript/test-runner/dist/index.js +345 -0
  1357. package/sdks/typescript/test-runner/dist/index.js.map +1 -0
  1358. package/sdks/typescript/test-runner/node_modules/.bin/pino +21 -0
  1359. package/sdks/typescript/test-runner/node_modules/.bin/tsc +21 -0
  1360. package/sdks/typescript/test-runner/node_modules/.bin/tsserver +21 -0
  1361. package/sdks/typescript/test-runner/node_modules/.bin/tsup +21 -0
  1362. package/sdks/typescript/test-runner/node_modules/.bin/tsup-node +21 -0
  1363. package/sdks/typescript/test-runner/node_modules/.bin/tsx +21 -0
  1364. package/sdks/typescript/test-runner/node_modules/.bin/vitest +21 -0
  1365. package/sdks/typescript/test-runner/package.json +27 -0
  1366. package/sdks/typescript/test-runner/src/index.ts +287 -0
  1367. package/sdks/typescript/test-runner/src/log.ts +194 -0
  1368. package/sdks/typescript/test-runner/tsconfig.json +11 -0
  1369. package/sdks/typescript/test-runner/tsup.config.ts +7 -0
  1370. package/sdks/typescript/test-runner/turbo.json +4 -0
  1371. package/sdks/typescript/test-runner/vitest.config.ts +16 -0
  1372. package/tests/load/README.md +28 -0
  1373. package/tests/load/actor-lifecycle/README.md +26 -0
  1374. package/tests/load/actor-lifecycle/actor.ts +41 -0
  1375. package/tests/load/actor-lifecycle/config.ts +14 -0
  1376. package/tests/load/actor-lifecycle/index.ts +62 -0
  1377. package/tests/load/actor-lifecycle/rivet_api.ts +140 -0
  1378. package/tests/load/actor-lifecycle/types.ts +17 -0
  1379. package/tests/load/node_modules/.bin/biome +21 -0
  1380. package/tests/load/node_modules/.bin/tsc +21 -0
  1381. package/tests/load/node_modules/.bin/tsserver +21 -0
  1382. package/tests/load/package.json +15 -0
  1383. package/tests/load/tsconfig.json +20 -0
  1384. package/tests/smoke/README.md +32 -0
  1385. package/tests/smoke/package.json +19 -0
  1386. package/tests/smoke/scripts/connect.ts +41 -0
  1387. package/tests/smoke/src/server/registry.ts +32 -0
  1388. package/tests/smoke/src/server/server.ts +7 -0
  1389. package/tests/smoke/src/smoke-test/index.ts +161 -0
  1390. package/tests/smoke/src/smoke-test/spawn-actor.ts +109 -0
  1391. package/tests/smoke/tsconfig.json +43 -0
  1392. package/tests/smoke/turbo.json +4 -0
@@ -0,0 +1,3044 @@
1
+ //! Implementation of a workflow database driver with UniversalDB and UniversalPubSub.
2
+ // TODO: Move code to smaller functions for readability
3
+
4
+ use std::{
5
+ collections::{HashMap, HashSet},
6
+ hash::{DefaultHasher, Hash, Hasher},
7
+ sync::Arc,
8
+ time::Instant,
9
+ };
10
+
11
+ use anyhow::{Context, Result};
12
+ use futures_util::{StreamExt, TryStreamExt, stream::BoxStream};
13
+ use rivet_util::Id;
14
+ use rivet_util::future::CustomInstrumentExt;
15
+ use serde_json::json;
16
+ use tokio::sync::Mutex;
17
+ use tracing::Instrument;
18
+ use universaldb::utils::{
19
+ FormalChunkedKey, FormalKey, IsolationLevel::*, end_of_key_range, keys::*,
20
+ };
21
+ use universaldb::{
22
+ options::{ConflictRangeType, MutationType, StreamingMode},
23
+ value::Value,
24
+ };
25
+
26
+ use rivet_metrics::KeyValue;
27
+
28
+ use super::{BumpSubSubject, Database, PulledWorkflowData, SignalData, WorkflowData};
29
+ use crate::{
30
+ error::{WorkflowError, WorkflowResult},
31
+ history::{
32
+ event::{
33
+ ActivityEvent, Event, EventData, EventType, LoopEvent, MessageSendEvent, RemovedEvent,
34
+ SignalEvent, SignalSendEvent, SleepEvent, SleepState, SubWorkflowEvent,
35
+ },
36
+ location::Location,
37
+ },
38
+ metrics,
39
+ worker::PING_INTERVAL,
40
+ };
41
+
42
+ mod debug;
43
+ mod keys;
44
+ mod subjects;
45
+ mod system;
46
+
47
+ /// How long before considering the leases of a given worker expired.
48
+ const WORKER_LOST_THRESHOLD_MS: i64 = rivet_util::duration::seconds(30);
49
+ /// How long before overwriting an existing metrics lock.
50
+ const METRICS_LOCK_TIMEOUT_MS: i64 = rivet_util::duration::seconds(30);
51
+
52
+ pub struct DatabaseKv {
53
+ pools: rivet_pools::Pools,
54
+ subspace: universaldb::utils::Subspace,
55
+ system: Mutex<system::SystemInfo>,
56
+ }
57
+
58
+ impl DatabaseKv {
59
+ /// Spawns a new thread and gracefully publishes a bump message to pubsub.
60
+ fn bump(&self, subject: BumpSubSubject) {
61
+ let Ok(pubsub) = self.pools.ups() else {
62
+ tracing::debug!("failed to acquire pubsub pool");
63
+ return;
64
+ };
65
+
66
+ let spawn_res = tokio::task::Builder::new().name("bump").spawn(
67
+ async move {
68
+ // Fail gracefully
69
+ if let Err(err) = pubsub
70
+ .publish(
71
+ &subjects::convert(subject),
72
+ &Vec::new(),
73
+ universalpubsub::PublishOpts::broadcast(),
74
+ )
75
+ .await
76
+ {
77
+ tracing::warn!(?err, "failed to publish bump message");
78
+ }
79
+ }
80
+ .instrument(tracing::info_span!("bump_worker_publish")),
81
+ );
82
+ if let Err(err) = spawn_res {
83
+ tracing::error!(?err, "failed to spawn bump task");
84
+ }
85
+ }
86
+ }
87
+
88
+ // MARK: UDB Helpers
89
+ impl DatabaseKv {
90
+ fn write_signal_wake_idxs(
91
+ &self,
92
+ workflow_id: Id,
93
+ wake_signals: &[&str],
94
+ tx: &universaldb::Transaction,
95
+ ) -> Result<()> {
96
+ for signal_name in wake_signals {
97
+ // Write to wake signals list
98
+ let wake_signal_key =
99
+ keys::workflow::WakeSignalKey::new(workflow_id, signal_name.to_string());
100
+ tx.set(
101
+ &self.subspace.pack(&wake_signal_key),
102
+ &wake_signal_key.serialize(())?,
103
+ );
104
+ }
105
+
106
+ Ok(())
107
+ }
108
+
109
+ fn write_sub_workflow_wake_idx(
110
+ &self,
111
+ workflow_id: Id,
112
+ workflow_name: &str,
113
+ sub_workflow_id: Id,
114
+ tx: &universaldb::Transaction,
115
+ ) -> Result<()> {
116
+ let sub_workflow_wake_key =
117
+ keys::wake::SubWorkflowWakeKey::new(sub_workflow_id, workflow_id);
118
+
119
+ tx.set(
120
+ &self.subspace.pack(&sub_workflow_wake_key),
121
+ &sub_workflow_wake_key.serialize(workflow_name.to_string())?,
122
+ );
123
+
124
+ Ok(())
125
+ }
126
+
127
+ async fn publish_signal_inner(
128
+ &self,
129
+ ray_id: Id,
130
+ workflow_id: Id,
131
+ signal_id: Id,
132
+ signal_name: &str,
133
+ body: &serde_json::value::RawValue,
134
+ tx: &universaldb::Transaction,
135
+ ) -> Result<()> {
136
+ tracing::debug!(
137
+ ?ray_id,
138
+ ?workflow_id,
139
+ ?signal_id,
140
+ ?signal_name,
141
+ "publishing signal"
142
+ );
143
+
144
+ let workflow_name_key = keys::workflow::NameKey::new(workflow_id);
145
+
146
+ // TODO: This does not check if the workflow is silenced
147
+ // Check if the workflow exists
148
+ let Some(workflow_name_entry) = tx
149
+ .get(&self.subspace.pack(&workflow_name_key), Serializable)
150
+ .await?
151
+ else {
152
+ return Err(WorkflowError::WorkflowNotFound.into());
153
+ };
154
+
155
+ let workflow_name = workflow_name_key.deserialize(&workflow_name_entry)?;
156
+
157
+ // Write name
158
+ let name_key = keys::signal::NameKey::new(signal_id);
159
+ tx.set(
160
+ &self.subspace.pack(&name_key),
161
+ &name_key.serialize(signal_name.to_string())?,
162
+ );
163
+
164
+ let signal_body_key = keys::signal::BodyKey::new(signal_id);
165
+
166
+ // Write signal body
167
+ for (i, chunk) in signal_body_key.split_ref(body)?.into_iter().enumerate() {
168
+ let chunk_key = signal_body_key.chunk(i);
169
+
170
+ tx.set(&self.subspace.pack(&chunk_key), &chunk);
171
+ }
172
+
173
+ // Write pending key
174
+ let pending_signal_key =
175
+ keys::workflow::PendingSignalKey::new(workflow_id, signal_name.to_string(), signal_id);
176
+
177
+ tx.set(
178
+ &self.subspace.pack(&pending_signal_key),
179
+ &pending_signal_key.serialize(())?,
180
+ );
181
+
182
+ // Write create ts
183
+ let create_ts_key = keys::signal::CreateTsKey::new(signal_id);
184
+ tx.set(
185
+ &self.subspace.pack(&create_ts_key),
186
+ &create_ts_key.serialize(pending_signal_key.ts)?,
187
+ );
188
+
189
+ // Write ray id
190
+ let ray_id_key = keys::signal::RayIdKey::new(signal_id);
191
+ tx.set(
192
+ &self.subspace.pack(&ray_id_key),
193
+ &ray_id_key.serialize(ray_id)?,
194
+ );
195
+
196
+ // Write workflow id
197
+ let workflow_id_key = keys::signal::WorkflowIdKey::new(signal_id);
198
+ tx.set(
199
+ &self.subspace.pack(&workflow_id_key),
200
+ &workflow_id_key.serialize(workflow_id)?,
201
+ );
202
+
203
+ let wake_signal_key =
204
+ keys::workflow::WakeSignalKey::new(workflow_id, signal_name.to_string());
205
+
206
+ // If the workflow currently has a wake signal key for this signal, wake it
207
+ if tx
208
+ .get(&self.subspace.pack(&wake_signal_key), Serializable)
209
+ .await?
210
+ .is_some()
211
+ {
212
+ let mut wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
213
+ workflow_name,
214
+ workflow_id,
215
+ keys::wake::WakeCondition::Signal { signal_id },
216
+ );
217
+ wake_condition_key.ts = pending_signal_key.ts;
218
+
219
+ // Add wake condition for workflow
220
+ tx.set(
221
+ &self.subspace.pack(&wake_condition_key),
222
+ &wake_condition_key.serialize(())?,
223
+ );
224
+ }
225
+
226
+ update_metric(
227
+ &tx.with_subspace(self.subspace.clone()),
228
+ None,
229
+ Some(keys::metric::GaugeMetric::SignalPending(
230
+ signal_name.to_string(),
231
+ )),
232
+ );
233
+
234
+ Ok(())
235
+ }
236
+
237
+ async fn dispatch_workflow_inner(
238
+ &self,
239
+ ray_id: Id,
240
+ workflow_id: Id,
241
+ workflow_name: &str,
242
+ tags: Option<&serde_json::Value>,
243
+ input: &serde_json::value::RawValue,
244
+ unique: bool,
245
+ tx: &universaldb::Transaction,
246
+ ) -> Result<Id> {
247
+ let tx = tx.with_subspace(self.subspace.clone());
248
+
249
+ if unique {
250
+ let empty_tags = json!({});
251
+
252
+ if let Some(existing_workflow_id) = self
253
+ .find_workflow_inner(workflow_name, tags.unwrap_or(&empty_tags), &tx)
254
+ .await?
255
+ {
256
+ tracing::debug!(?existing_workflow_id, "found existing workflow");
257
+ return Ok(existing_workflow_id);
258
+ }
259
+ }
260
+
261
+ tx.write(
262
+ &keys::workflow::CreateTsKey::new(workflow_id),
263
+ rivet_util::timestamp::now(),
264
+ )?;
265
+
266
+ tx.write(
267
+ &keys::workflow::NameKey::new(workflow_id),
268
+ workflow_name.to_string(),
269
+ )?;
270
+
271
+ tx.write(&keys::workflow::RayIdKey::new(workflow_id), ray_id)?;
272
+
273
+ // Write tags
274
+ let tags = tags
275
+ .map(|x| {
276
+ x.as_object()
277
+ .ok_or_else(|| WorkflowError::InvalidTags("must be an object".to_string()))
278
+ })
279
+ .transpose()?
280
+ .into_iter()
281
+ .flatten()
282
+ .map(|(k, v)| Ok((k.clone(), value_to_str(v)?)))
283
+ .collect::<WorkflowResult<Vec<_>>>()?;
284
+
285
+ for (k, v) in &tags {
286
+ // Write tag key
287
+ tx.write(
288
+ &keys::workflow::TagKey::new(workflow_id, k.clone(), v.clone()),
289
+ (),
290
+ )?;
291
+
292
+ // Write "by name and first tag" secondary index
293
+ let rest_of_tags = tags
294
+ .iter()
295
+ .filter(|(k2, _)| k2 != k)
296
+ .map(|(k, v)| (k.clone(), v.clone()))
297
+ .collect();
298
+
299
+ tx.write(
300
+ &keys::workflow::ByNameAndTagKey::new(
301
+ workflow_name.to_string(),
302
+ k.clone(),
303
+ v.clone(),
304
+ workflow_id,
305
+ ),
306
+ rest_of_tags,
307
+ )?;
308
+ }
309
+
310
+ // Write null key for the "by name and first tag" secondary index (all workflows have this)
311
+ tx.write(
312
+ &keys::workflow::ByNameAndTagKey::null(workflow_name.to_string(), workflow_id),
313
+ tags,
314
+ )?;
315
+
316
+ // Write input
317
+ let input_key = keys::workflow::InputKey::new(workflow_id);
318
+
319
+ for (i, chunk) in input_key.split_ref(input)?.into_iter().enumerate() {
320
+ let chunk_key = input_key.chunk(i);
321
+
322
+ tx.set(&self.subspace.pack(&chunk_key), &chunk);
323
+ }
324
+
325
+ // Write immediate wake condition
326
+ tx.write(
327
+ &keys::wake::WorkflowWakeConditionKey::new(
328
+ workflow_name.to_string(),
329
+ workflow_id,
330
+ keys::wake::WakeCondition::Immediate,
331
+ ),
332
+ (),
333
+ )?;
334
+
335
+ tx.write(&keys::workflow::HasWakeConditionKey::new(workflow_id), ())?;
336
+
337
+ // Write metric
338
+ update_metric(
339
+ &tx,
340
+ None,
341
+ Some(keys::metric::GaugeMetric::WorkflowSleeping(
342
+ workflow_name.to_string(),
343
+ )),
344
+ );
345
+
346
+ Ok(workflow_id)
347
+ }
348
+
349
+ async fn find_workflow_inner(
350
+ &self,
351
+ workflow_name: &str,
352
+ tags: &serde_json::Value,
353
+ tx: &universaldb::Transaction,
354
+ ) -> Result<Option<Id>> {
355
+ // Convert to flat vec of strings
356
+ let mut tag_iter = tags
357
+ .as_object()
358
+ .ok_or_else(|| WorkflowError::InvalidTags("must be an object".to_string()))?
359
+ .iter()
360
+ .map(|(k, v)| Result::<_>::Ok((k.clone(), value_to_str(v)?)));
361
+ let first_tag = tag_iter.next().transpose()?;
362
+ let rest_of_tags = tag_iter.collect::<Result<Vec<_>, _>>()?;
363
+
364
+ let workflow_by_name_and_tag_subspace =
365
+ if let Some((first_tag_key, first_tag_value)) = first_tag {
366
+ self.subspace
367
+ .subspace(&keys::workflow::ByNameAndTagKey::subspace(
368
+ workflow_name.to_string(),
369
+ first_tag_key,
370
+ first_tag_value,
371
+ ))
372
+ } else {
373
+ // No tags provided, use null subspace. Every workflow has a null key for its tags
374
+ // under the `ByNameAndTagKey` subspace
375
+ self.subspace
376
+ .subspace(&keys::workflow::ByNameAndTagKey::null_subspace(
377
+ workflow_name.to_string(),
378
+ ))
379
+ };
380
+
381
+ let mut stream = tx.get_ranges_keyvalues(
382
+ universaldb::RangeOption {
383
+ mode: StreamingMode::Iterator,
384
+ ..(&workflow_by_name_and_tag_subspace).into()
385
+ },
386
+ Serializable,
387
+ );
388
+
389
+ loop {
390
+ let Some(entry) = stream.try_next().await? else {
391
+ return Ok(None);
392
+ };
393
+
394
+ // Unpack key
395
+ let workflow_by_name_and_tag_key = self
396
+ .subspace
397
+ .unpack::<keys::workflow::ByNameAndTagKey>(&entry.key())?;
398
+
399
+ // Deserialize value
400
+ let wf_rest_of_tags = workflow_by_name_and_tag_key.deserialize(entry.value())?;
401
+
402
+ // Compute intersection between wf tags and input
403
+ let tags_match = rest_of_tags.iter().all(|(k, v)| {
404
+ wf_rest_of_tags
405
+ .iter()
406
+ .any(|(wf_k, wf_v)| k == wf_k && v == wf_v)
407
+ });
408
+
409
+ // Return first signal that matches the tags
410
+ if tags_match {
411
+ break Ok(Some(workflow_by_name_and_tag_key.workflow_id));
412
+ }
413
+ }
414
+ }
415
+ }
416
+
417
+ #[async_trait::async_trait]
418
+ impl Database for DatabaseKv {
419
+ fn worker_poll_interval(&self) -> std::time::Duration {
420
+ std::time::Duration::from_secs(4)
421
+ }
422
+
423
+ async fn from_pools(pools: rivet_pools::Pools) -> anyhow::Result<Arc<Self>> {
424
+ Ok(Arc::new(DatabaseKv {
425
+ pools,
426
+ subspace: universaldb::utils::Subspace::new(&(RIVET, GASOLINE, KV)),
427
+ system: Mutex::new(system::SystemInfo::new()),
428
+ }))
429
+ }
430
+
431
+ #[tracing::instrument(skip_all)]
432
+ async fn bump_sub<'a, 'b>(
433
+ &'a self,
434
+ subject: BumpSubSubject,
435
+ ) -> WorkflowResult<BoxStream<'b, ()>> {
436
+ let mut subscriber = self
437
+ .pools
438
+ .ups()
439
+ .map_err(WorkflowError::PoolsGeneric)?
440
+ .subscribe(&subjects::convert(subject))
441
+ .await
442
+ .map_err(|x| WorkflowError::CreateSubscription(x.into()))?;
443
+
444
+ let stream = async_stream::stream! {
445
+ loop {
446
+ use universalpubsub::NextOutput;
447
+ match subscriber.next().await {
448
+ Ok(NextOutput::Message(_)) => yield (),
449
+ Ok(NextOutput::Unsubscribed) => break,
450
+ Err(err) => {
451
+ tracing::warn!(?err, "error in worker wake stream");
452
+ break;
453
+ }
454
+ }
455
+ }
456
+ };
457
+
458
+ Ok(stream.boxed())
459
+ }
460
+
461
+ #[tracing::instrument(skip_all)]
462
+ async fn clear_expired_leases(&self, _worker_id: Id) -> WorkflowResult<()> {
463
+ let (lost_worker_ids, expired_workflow_count) = self
464
+ .pools
465
+ .udb()
466
+ .map_err(WorkflowError::PoolsGeneric)?
467
+ .run(|tx| {
468
+ async move {
469
+ let now = rivet_util::timestamp::now();
470
+
471
+ let mut last_ping_cache: Vec<(Id, i64)> = Vec::new();
472
+ let mut lost_worker_ids = HashSet::new();
473
+ let mut expired_workflow_count = 0;
474
+
475
+ let lease_subspace = self
476
+ .subspace
477
+ .subspace(&keys::workflow::LeaseKey::subspace());
478
+
479
+ // List all active leases
480
+ let mut stream = tx.get_ranges_keyvalues(
481
+ universaldb::RangeOption {
482
+ mode: StreamingMode::WantAll,
483
+ ..(&lease_subspace).into()
484
+ },
485
+ // Not Serializable because we don't want this to conflict with other queries which write
486
+ // leases
487
+ Snapshot,
488
+ );
489
+
490
+ while let Some(lease_key_entry) = stream.try_next().await? {
491
+ let lease_key = self
492
+ .subspace
493
+ .unpack::<keys::workflow::LeaseKey>(lease_key_entry.key())?;
494
+ let (workflow_name, worker_id) =
495
+ lease_key.deserialize(lease_key_entry.value())?;
496
+ let last_ping_ts_key = keys::worker::LastPingTsKey::new(worker_id);
497
+
498
+ // Get last ping of worker for this lease
499
+ let last_ping_ts = if let Some((_, last_ping_ts)) =
500
+ last_ping_cache.iter().find(|(k, _)| k == &worker_id)
501
+ {
502
+ *last_ping_ts
503
+ } else if let Some(last_ping_entry) = tx
504
+ .get(
505
+ &self.subspace.pack(&last_ping_ts_key),
506
+ // Not Serializable because we don't want this to conflict
507
+ Snapshot,
508
+ )
509
+ .await?
510
+ {
511
+ // Deserialize last ping value
512
+ let last_ping_ts = last_ping_ts_key.deserialize(&last_ping_entry)?;
513
+
514
+ // Update cache
515
+ last_ping_cache.push((worker_id, last_ping_ts));
516
+
517
+ last_ping_ts
518
+ } else {
519
+ // Update cache
520
+ last_ping_cache.push((worker_id, 0));
521
+
522
+ 0
523
+ };
524
+
525
+ // Worker has not pinged within the threshold, meaning the lease is expired
526
+ if last_ping_ts < now - WORKER_LOST_THRESHOLD_MS {
527
+ // Check if the workflow is silenced and ignore
528
+ let silence_ts_key =
529
+ keys::workflow::SilenceTsKey::new(lease_key.workflow_id);
530
+ if tx
531
+ .get(&self.subspace.pack(&silence_ts_key), Serializable)
532
+ .await?
533
+ .is_some()
534
+ {
535
+ continue;
536
+ }
537
+
538
+ // NOTE: We add a read conflict here so this query conflicts with any other
539
+ // `clear_expired_leases` queries running at the same time (will conflict with the
540
+ // following `tx.clear`).
541
+ tx.add_conflict_range(
542
+ lease_key_entry.key(),
543
+ &end_of_key_range(lease_key_entry.key()),
544
+ ConflictRangeType::Read,
545
+ )?;
546
+
547
+ // Clear lease
548
+ tx.clear(lease_key_entry.key());
549
+ let worker_id_key =
550
+ keys::workflow::WorkerIdKey::new(lease_key.workflow_id);
551
+ tx.clear(&self.subspace.pack(&worker_id_key));
552
+
553
+ // Add immediate wake for workflow
554
+ let wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
555
+ workflow_name.to_string(),
556
+ lease_key.workflow_id,
557
+ keys::wake::WakeCondition::Immediate,
558
+ );
559
+ tx.set(
560
+ &self.subspace.pack(&wake_condition_key),
561
+ &wake_condition_key.serialize(())?,
562
+ );
563
+
564
+ update_metric(
565
+ &tx.with_subspace(self.subspace.clone()),
566
+ Some(keys::metric::GaugeMetric::WorkflowActive(
567
+ workflow_name.to_string(),
568
+ )),
569
+ Some(keys::metric::GaugeMetric::WorkflowSleeping(
570
+ workflow_name.to_string(),
571
+ )),
572
+ );
573
+
574
+ expired_workflow_count += 1;
575
+ lost_worker_ids.insert(worker_id);
576
+
577
+ tracing::debug!(?lease_key.workflow_id, "failed over wf");
578
+ }
579
+ }
580
+
581
+ Ok((lost_worker_ids, expired_workflow_count))
582
+ }
583
+ })
584
+ .custom_instrument(tracing::info_span!("clear_expired_leases_tx"))
585
+ .await
586
+ .map_err(WorkflowError::Udb)?;
587
+
588
+ if expired_workflow_count != 0 {
589
+ tracing::info!(
590
+ worker_ids=?lost_worker_ids,
591
+ total_workflows=%expired_workflow_count,
592
+ "handled failover",
593
+ );
594
+
595
+ self.bump(BumpSubSubject::Worker);
596
+ }
597
+
598
+ Ok(())
599
+ }
600
+
601
+ #[tracing::instrument(skip_all)]
602
+ async fn publish_metrics(&self, _worker_id: Id) -> WorkflowResult<()> {
603
+ // Attempt to be the only worker publishing metrics by writing to the lock key
604
+ let acquired_lock = self
605
+ .pools
606
+ .udb()
607
+ .map_err(WorkflowError::PoolsGeneric)?
608
+ .run(|tx| {
609
+ async move {
610
+ let tx = tx.with_subspace(self.subspace.clone());
611
+
612
+ // Read existing lock
613
+ let lock_expired = if let Some(lock_ts) = tx
614
+ .read_opt(&keys::worker::MetricsLockKey::new(), Serializable)
615
+ .await?
616
+ {
617
+ lock_ts < rivet_util::timestamp::now() - METRICS_LOCK_TIMEOUT_MS
618
+ } else {
619
+ true
620
+ };
621
+
622
+ if lock_expired {
623
+ // Write to lock key. UDB transactions guarantee that if multiple workers are running this
624
+ // query at the same time only one will succeed which means only one will have the lock.
625
+ tx.write(
626
+ &keys::worker::MetricsLockKey::new(),
627
+ rivet_util::timestamp::now(),
628
+ )?;
629
+ }
630
+
631
+ Ok(lock_expired)
632
+ }
633
+ })
634
+ .custom_instrument(tracing::info_span!("acquire_lock_tx"))
635
+ .await
636
+ .map_err(WorkflowError::Udb)?;
637
+
638
+ if acquired_lock {
639
+ let entries = self
640
+ .pools
641
+ .udb()
642
+ .map_err(WorkflowError::PoolsGeneric)?
643
+ .run(|tx| async move {
644
+ let tx = tx.with_subspace(self.subspace.clone());
645
+
646
+ let metrics_subspace = self
647
+ .subspace
648
+ .subspace(&keys::metric::GaugeMetricKey::subspace());
649
+ tx.get_ranges_keyvalues(
650
+ universaldb::RangeOption {
651
+ mode: StreamingMode::WantAll,
652
+ ..(&metrics_subspace).into()
653
+ },
654
+ Serializable,
655
+ )
656
+ .map(|res| match res {
657
+ Ok(entry) => tx.read_entry::<keys::metric::GaugeMetricKey>(&entry),
658
+ Err(err) => Err(err.into()),
659
+ })
660
+ .try_collect::<Vec<_>>()
661
+ .await
662
+ })
663
+ .custom_instrument(tracing::info_span!("read_metrics_tx"))
664
+ .await
665
+ .map_err(WorkflowError::Udb)?;
666
+
667
+ let mut total_workflow_counts: Vec<(String, usize)> = Vec::new();
668
+
669
+ for (key, count) in entries {
670
+ match key.metric {
671
+ keys::metric::GaugeMetric::WorkflowActive(workflow_name) => {
672
+ metrics::WORKFLOW_ACTIVE.record(
673
+ count as u64,
674
+ &[KeyValue::new("workflow_name", workflow_name.clone())],
675
+ );
676
+
677
+ if let Some(entry) = total_workflow_counts
678
+ .iter_mut()
679
+ .find(|(name, _)| name == &workflow_name)
680
+ {
681
+ entry.1 += 1;
682
+ } else {
683
+ total_workflow_counts.push((workflow_name, 1));
684
+ }
685
+ }
686
+ keys::metric::GaugeMetric::WorkflowSleeping(workflow_name) => {
687
+ metrics::WORKFLOW_SLEEPING.record(
688
+ count as u64,
689
+ &[KeyValue::new("workflow_name", workflow_name.clone())],
690
+ );
691
+
692
+ if let Some(entry) = total_workflow_counts
693
+ .iter_mut()
694
+ .find(|(name, _)| name == &workflow_name)
695
+ {
696
+ entry.1 += 1;
697
+ } else {
698
+ total_workflow_counts.push((workflow_name, 1));
699
+ }
700
+ }
701
+ keys::metric::GaugeMetric::WorkflowDead(workflow_name, error) => {
702
+ metrics::WORKFLOW_DEAD.record(
703
+ count as u64,
704
+ &[
705
+ KeyValue::new("workflow_name", workflow_name.clone()),
706
+ KeyValue::new("error", error),
707
+ ],
708
+ );
709
+
710
+ if let Some(entry) = total_workflow_counts
711
+ .iter_mut()
712
+ .find(|(name, _)| name == &workflow_name)
713
+ {
714
+ entry.1 += 1;
715
+ } else {
716
+ total_workflow_counts.push((workflow_name, 1));
717
+ }
718
+ }
719
+ keys::metric::GaugeMetric::WorkflowComplete(workflow_name) => {
720
+ if let Some(entry) = total_workflow_counts
721
+ .iter_mut()
722
+ .find(|(name, _)| name == &workflow_name)
723
+ {
724
+ entry.1 += 1;
725
+ } else {
726
+ total_workflow_counts.push((workflow_name, 1));
727
+ }
728
+ }
729
+ keys::metric::GaugeMetric::SignalPending(signal_name) => {
730
+ metrics::SIGNAL_PENDING
731
+ .record(count as u64, &[KeyValue::new("signal_name", signal_name)]);
732
+ }
733
+ }
734
+ }
735
+
736
+ for (workflow_name, count) in total_workflow_counts {
737
+ metrics::WORKFLOW_TOTAL.record(
738
+ count as u64,
739
+ &[KeyValue::new("workflow_name", workflow_name.clone())],
740
+ );
741
+ }
742
+
743
+ // Clear lock
744
+ self.pools
745
+ .udb()
746
+ .map_err(WorkflowError::PoolsGeneric)?
747
+ .run(|tx| async move {
748
+ let metrics_lock_key = keys::worker::MetricsLockKey::new();
749
+ tx.clear(&self.subspace.pack(&metrics_lock_key));
750
+
751
+ Ok(())
752
+ })
753
+ .custom_instrument(tracing::info_span!("clear_lock_tx"))
754
+ .await
755
+ .map_err(WorkflowError::Udb)?;
756
+ }
757
+
758
+ Ok(())
759
+ }
760
+
761
+ #[tracing::instrument(skip_all)]
762
+ async fn update_worker_ping(&self, worker_id: Id) -> WorkflowResult<()> {
763
+ metrics::WORKER_LAST_PING.record(
764
+ rivet_util::timestamp::now() as u64,
765
+ &[KeyValue::new("worker_id", worker_id.to_string())],
766
+ );
767
+
768
+ self.pools
769
+ .udb()
770
+ .map_err(WorkflowError::PoolsGeneric)?
771
+ .run(|tx| async move {
772
+ let tx = tx.with_subspace(self.subspace.clone());
773
+
774
+ let last_ping_ts = rivet_util::timestamp::now();
775
+ let last_ping_ts_key = keys::worker::LastPingTsKey::new(worker_id);
776
+
777
+ if let Some(last_last_ping_ts) =
778
+ tx.read_opt(&last_ping_ts_key, Serializable).await?
779
+ {
780
+ let active_worker_idx_key =
781
+ keys::worker::ActiveWorkerIdxKey::new(last_last_ping_ts, worker_id);
782
+ tx.delete(&active_worker_idx_key);
783
+ }
784
+
785
+ tx.write(&last_ping_ts_key, last_ping_ts)?;
786
+
787
+ let active_worker_idx_key =
788
+ keys::worker::ActiveWorkerIdxKey::new(last_ping_ts, worker_id);
789
+ tx.write(&active_worker_idx_key, ())?;
790
+
791
+ Ok(())
792
+ })
793
+ .custom_instrument(tracing::info_span!("update_worker_ping_tx"))
794
+ .await
795
+ .map_err(WorkflowError::Udb)?;
796
+
797
+ Ok(())
798
+ }
799
+
800
+ #[tracing::instrument(skip_all)]
801
+ async fn mark_worker_inactive(&self, worker_id: Id) -> WorkflowResult<()> {
802
+ self.pools
803
+ .udb()
804
+ .map_err(WorkflowError::PoolsGeneric)?
805
+ .run(|tx| async move {
806
+ let last_ping_ts_key = keys::worker::LastPingTsKey::new(worker_id);
807
+
808
+ if let Some(last_last_ping_ts) =
809
+ tx.read_opt(&last_ping_ts_key, Serializable).await?
810
+ {
811
+ let active_worker_idx_key =
812
+ keys::worker::ActiveWorkerIdxKey::new(last_last_ping_ts, worker_id);
813
+ tx.delete(&active_worker_idx_key);
814
+ }
815
+
816
+ Ok(())
817
+ })
818
+ .custom_instrument(tracing::info_span!("mark_worker_inactive_tx"))
819
+ .await
820
+ .map_err(WorkflowError::Udb)?;
821
+
822
+ Ok(())
823
+ }
824
+
825
+ #[tracing::instrument(skip_all, fields(%workflow_id, %workflow_name, unique))]
826
+ async fn dispatch_workflow(
827
+ &self,
828
+ ray_id: Id,
829
+ workflow_id: Id,
830
+ workflow_name: &str,
831
+ tags: Option<&serde_json::Value>,
832
+ input: &serde_json::value::RawValue,
833
+ unique: bool,
834
+ ) -> WorkflowResult<Id> {
835
+ let workflow_id = self
836
+ .pools
837
+ .udb()
838
+ .map_err(WorkflowError::PoolsGeneric)?
839
+ .run(|tx| async move {
840
+ self.dispatch_workflow_inner(
841
+ ray_id,
842
+ workflow_id,
843
+ workflow_name,
844
+ tags,
845
+ input,
846
+ unique,
847
+ &tx,
848
+ )
849
+ .await
850
+ })
851
+ .custom_instrument(tracing::info_span!("dispatch_workflow_tx"))
852
+ .await
853
+ .map_err(WorkflowError::Udb)?;
854
+
855
+ self.bump(BumpSubSubject::Worker);
856
+
857
+ Ok(workflow_id)
858
+ }
859
+
860
+ #[tracing::instrument(skip_all, fields(?workflow_ids))]
861
+ async fn get_workflows(&self, workflow_ids: Vec<Id>) -> WorkflowResult<Vec<WorkflowData>> {
862
+ self.pools
863
+ .udb()
864
+ .map_err(WorkflowError::PoolsGeneric)?
865
+ .run(|tx| {
866
+ let workflow_ids = workflow_ids.clone();
867
+ async move {
868
+ futures_util::stream::iter(workflow_ids)
869
+ .map(|workflow_id| {
870
+ let tx = tx.clone();
871
+ async move {
872
+ let input_key = keys::workflow::InputKey::new(workflow_id);
873
+ let input_subspace = self.subspace.subspace(&input_key);
874
+ let state_key = keys::workflow::StateKey::new(workflow_id);
875
+ let state_subspace = self.subspace.subspace(&state_key);
876
+ let output_key = keys::workflow::OutputKey::new(workflow_id);
877
+ let output_subspace = self.subspace.subspace(&output_key);
878
+ let has_wake_condition_key =
879
+ keys::workflow::HasWakeConditionKey::new(workflow_id);
880
+
881
+ // Read input and output
882
+ let (
883
+ input_chunks,
884
+ state_chunks,
885
+ output_chunks,
886
+ has_wake_condition_entry,
887
+ ) = tokio::try_join!(
888
+ tx.get_ranges_keyvalues(
889
+ universaldb::RangeOption {
890
+ mode: StreamingMode::WantAll,
891
+ ..(&input_subspace).into()
892
+ },
893
+ Serializable,
894
+ )
895
+ .try_collect::<Vec<_>>(),
896
+ tx.get_ranges_keyvalues(
897
+ universaldb::RangeOption {
898
+ mode: StreamingMode::WantAll,
899
+ ..(&state_subspace).into()
900
+ },
901
+ Serializable,
902
+ )
903
+ .try_collect::<Vec<_>>(),
904
+ tx.get_ranges_keyvalues(
905
+ universaldb::RangeOption {
906
+ mode: StreamingMode::WantAll,
907
+ ..(&output_subspace).into()
908
+ },
909
+ Serializable,
910
+ )
911
+ .try_collect::<Vec<_>>(),
912
+ tx.get(
913
+ &self.subspace.pack(&has_wake_condition_key),
914
+ Serializable
915
+ ),
916
+ )?;
917
+
918
+ if input_chunks.is_empty() {
919
+ Ok(None)
920
+ } else {
921
+ let input = input_key.combine(input_chunks)?;
922
+
923
+ let state = if state_chunks.is_empty() {
924
+ serde_json::value::RawValue::NULL.to_owned()
925
+ } else {
926
+ state_key.combine(state_chunks)?
927
+ };
928
+
929
+ let output = if output_chunks.is_empty() {
930
+ None
931
+ } else {
932
+ Some(output_key.combine(output_chunks)?)
933
+ };
934
+
935
+ Ok(Some(WorkflowData {
936
+ workflow_id,
937
+ input,
938
+ state,
939
+ output,
940
+ has_wake_condition: has_wake_condition_entry.is_some(),
941
+ }))
942
+ }
943
+ }
944
+ })
945
+ .buffered(256)
946
+ .try_filter_map(|x| std::future::ready(Ok(x)))
947
+ .try_collect::<Vec<_>>()
948
+ .instrument(tracing::trace_span!("get_workflows"))
949
+ .await
950
+ }
951
+ })
952
+ .custom_instrument(tracing::info_span!("get_workflow_tx"))
953
+ .await
954
+ .map_err(WorkflowError::Udb)
955
+ }
956
+
957
+ /// Returns the first incomplete workflow with the given name and tags, first meaning the one with the
958
+ /// lowest id value (interpreted as u128) because its in a KV store. There is no way to get any other
959
+ /// workflow besides the first.
960
+ #[tracing::instrument(skip_all, fields(%workflow_name))]
961
+ async fn find_workflow(
962
+ &self,
963
+ workflow_name: &str,
964
+ tags: &serde_json::Value,
965
+ ) -> WorkflowResult<Option<Id>> {
966
+ let start_instant = Instant::now();
967
+
968
+ let workflow_id = self
969
+ .pools
970
+ .udb()
971
+ .map_err(WorkflowError::PoolsGeneric)?
972
+ .run(|tx| async move { self.find_workflow_inner(workflow_name, tags, &tx).await })
973
+ .custom_instrument(tracing::info_span!("find_workflow_tx"))
974
+ .await
975
+ .map_err(WorkflowError::Udb)?;
976
+
977
+ let dt = start_instant.elapsed().as_secs_f64();
978
+ metrics::FIND_WORKFLOWS_DURATION.record(
979
+ dt,
980
+ &[KeyValue::new("workflow_name", workflow_name.to_string())],
981
+ );
982
+
983
+ Ok(workflow_id)
984
+ }
985
+
986
+ #[tracing::instrument(skip_all)]
987
+ async fn pull_workflows(
988
+ &self,
989
+ worker_id: Id,
990
+ filter: &[&str],
991
+ ) -> WorkflowResult<Vec<PulledWorkflowData>> {
992
+ let start_instant = Instant::now();
993
+ let owned_filter = filter
994
+ .into_iter()
995
+ .map(|x| x.to_string())
996
+ .collect::<Vec<_>>();
997
+
998
+ let leased_workflows = self
999
+ .pools
1000
+ .udb()
1001
+ .map_err(WorkflowError::PoolsGeneric)?
1002
+ .run(|tx| {
1003
+ let owned_filter = owned_filter.clone();
1004
+
1005
+ async move {
1006
+ let tx = tx.with_subspace(self.subspace.clone());
1007
+ let now = rivet_util::timestamp::now();
1008
+
1009
+ // All wake conditions with a timestamp after this timestamp will be pulled
1010
+ let pull_before = now + i64::try_from(self.worker_poll_interval().as_millis())?;
1011
+ // Only consider workers that have pinged within 2 ping intervals ago
1012
+ let active_workers_after = now - i64::try_from(PING_INTERVAL.as_millis() * 2)?;
1013
+
1014
+ // Determine load shedding ratio based on linear mapping on cpu usage. We will gradually
1015
+ // pull less workflows as the cpu usage increases
1016
+ let cpu_usage = { self.system.lock().await.cpu_usage() };
1017
+ let load_shed_ratio_x1000 =
1018
+ calc_pull_ratio((cpu_usage.max(100.0) * 10.0) as u64, 500, 1000, 800, 100);
1019
+
1020
+ let active_worker_subspace_start = tx.pack(
1021
+ &keys::worker::ActiveWorkerIdxKey::subspace(active_workers_after),
1022
+ );
1023
+ let active_worker_subspace_end = self
1024
+ .subspace
1025
+ .subspace(&keys::worker::ActiveWorkerIdxKey::entire_subspace())
1026
+ .range()
1027
+ .1;
1028
+
1029
+ // Pull all available wake conditions from all registered wf names
1030
+ let (mut active_worker_ids, wake_keys) = tokio::try_join!(
1031
+ // Check
1032
+ tx.get_ranges_keyvalues(
1033
+ universaldb::RangeOption {
1034
+ mode: StreamingMode::WantAll,
1035
+ ..(active_worker_subspace_start, active_worker_subspace_end).into()
1036
+ },
1037
+ // This is Snapshot to reduce contention and exact timestamps are not important
1038
+ Snapshot,
1039
+ )
1040
+ .map(|res| {
1041
+ let key = tx.unpack::<keys::worker::ActiveWorkerIdxKey>(res?.key())?;
1042
+ Ok(key.worker_id)
1043
+ })
1044
+ .try_collect::<Vec<_>>(),
1045
+ futures_util::stream::iter(owned_filter)
1046
+ .map(|wf_name| {
1047
+ let wake_subspace_start = end_of_key_range(&tx.pack(
1048
+ &keys::wake::WorkflowWakeConditionKey::subspace_without_ts(
1049
+ wf_name.clone(),
1050
+ ),
1051
+ ));
1052
+ let wake_subspace_end =
1053
+ tx.pack(&keys::wake::WorkflowWakeConditionKey::subspace(
1054
+ wf_name,
1055
+ pull_before,
1056
+ ));
1057
+
1058
+ tx.get_ranges_keyvalues(
1059
+ universaldb::RangeOption {
1060
+ mode: StreamingMode::WantAll,
1061
+ ..(wake_subspace_start, wake_subspace_end).into()
1062
+ },
1063
+ // This is Snapshot to reduce contention with any new wake conditions
1064
+ // being inserted. Conflicts are handled by workflow leases.
1065
+ Snapshot,
1066
+ )
1067
+ })
1068
+ .flatten()
1069
+ .map(|res| tx.unpack::<keys::wake::WorkflowWakeConditionKey>(res?.key()))
1070
+ .try_collect::<Vec<_>>(),
1071
+ )?;
1072
+
1073
+ // Sort for consistency across all workers
1074
+ active_worker_ids.sort();
1075
+
1076
+ // Get a globally unique idx for the current worker relative to all active workers
1077
+ let current_worker_idx = if let Some(current_worker_idx) = active_worker_ids
1078
+ .iter()
1079
+ .enumerate()
1080
+ .find_map(|(i, other_worker_id)| {
1081
+ (&worker_id == other_worker_id).then_some(i)
1082
+ }) {
1083
+ current_worker_idx as u64
1084
+ } else {
1085
+ tracing::error!(
1086
+ ?worker_id,
1087
+ "current worker should have valid ping, defaulting to worker index 0"
1088
+ );
1089
+
1090
+ 0
1091
+ };
1092
+ let active_worker_count = active_worker_ids.len() as u64;
1093
+
1094
+ // Collect name and deadline ts for each wf id
1095
+ let mut dedup_workflows: Vec<MinimalPulledWorkflow> = Vec::new();
1096
+ for wake_key in &wake_keys {
1097
+ if let Some(wf) = dedup_workflows
1098
+ .iter_mut()
1099
+ .find(|wf| wf.workflow_id == wake_key.workflow_id)
1100
+ {
1101
+ let key_wake_deadline_ts = wake_key.condition.deadline_ts();
1102
+
1103
+ // Update wake condition ts if earlier
1104
+ if wake_key.ts < wf.earliest_wake_condition_ts {
1105
+ wf.earliest_wake_condition_ts = wake_key.ts;
1106
+ }
1107
+
1108
+ // Update wake deadline ts if earlier
1109
+ if wf.wake_deadline_ts.is_none()
1110
+ || key_wake_deadline_ts < wf.wake_deadline_ts
1111
+ {
1112
+ wf.wake_deadline_ts = key_wake_deadline_ts;
1113
+ }
1114
+
1115
+ continue;
1116
+ }
1117
+
1118
+ dedup_workflows.push(MinimalPulledWorkflow {
1119
+ workflow_id: wake_key.workflow_id,
1120
+ workflow_name: wake_key.workflow_name.clone(),
1121
+ wake_deadline_ts: wake_key.condition.deadline_ts(),
1122
+ earliest_wake_condition_ts: wake_key.ts,
1123
+ });
1124
+ }
1125
+
1126
+ // Filter workflows in a way that spreads all current pending workflows across all active
1127
+ // workers evenly
1128
+ let assigned_workflows = dedup_workflows.into_iter().filter(|wf| {
1129
+ let mut hasher = DefaultHasher::new();
1130
+
1131
+ // Earliest wake condition ts is consistent for hashing purposes because when it
1132
+ // changes it means a worker has leased it
1133
+ wf.earliest_wake_condition_ts.hash(&mut hasher);
1134
+ let wf_hash = hasher.finish();
1135
+
1136
+ let pseudorandom_value_x1000 = {
1137
+ // Add a little pizazz to the hash so its a different number than wf_hash but
1138
+ // still consistent
1139
+ 1234i32.hash(&mut hasher);
1140
+ hasher.finish() % 1000 // 0-1000
1141
+ };
1142
+
1143
+ if pseudorandom_value_x1000 < load_shed_ratio_x1000 {
1144
+ return false;
1145
+ }
1146
+
1147
+ let wf_worker_idx = wf_hash % active_worker_count;
1148
+
1149
+ // Every worker pulls workflows that has to the current worker as well as the next
1150
+ // worker for redundancy. this results in increased txn conflicts but less chance of
1151
+ // orphaned workflows
1152
+ let next_worker_idx = (current_worker_idx + 1) % active_worker_count;
1153
+
1154
+ wf_worker_idx == current_worker_idx || wf_worker_idx == next_worker_idx
1155
+ });
1156
+
1157
+ // Check leases
1158
+ let leased_workflows = futures_util::stream::iter(assigned_workflows)
1159
+ .map(|wf| {
1160
+ let tx = tx.clone();
1161
+ async move {
1162
+ let lease_key = keys::workflow::LeaseKey::new(wf.workflow_id);
1163
+
1164
+ // Check lease
1165
+ if tx.exists(&lease_key, Serializable).await? {
1166
+ Result::<_>::Ok(None)
1167
+ } else {
1168
+ tx.write(&lease_key, (wf.workflow_name.clone(), worker_id))?;
1169
+
1170
+ tx.write(
1171
+ &keys::workflow::WorkerIdKey::new(wf.workflow_id),
1172
+ worker_id,
1173
+ )?;
1174
+
1175
+ update_metric(
1176
+ &tx,
1177
+ Some(keys::metric::GaugeMetric::WorkflowSleeping(
1178
+ wf.workflow_name.clone(),
1179
+ )),
1180
+ Some(keys::metric::GaugeMetric::WorkflowActive(
1181
+ wf.workflow_name.clone(),
1182
+ )),
1183
+ );
1184
+
1185
+ Ok(Some(wf))
1186
+ }
1187
+ }
1188
+ })
1189
+ // TODO: How to get rid of this buffer?
1190
+ .buffer_unordered(1024)
1191
+ .try_filter_map(|x| std::future::ready(Ok(x)))
1192
+ .try_collect::<Vec<_>>()
1193
+ .instrument(tracing::trace_span!("map_to_leased_workflows"))
1194
+ .await?;
1195
+
1196
+ // Clear all wake conditions from workflows that we have leased
1197
+ for wake_key in &wake_keys {
1198
+ if !leased_workflows
1199
+ .iter()
1200
+ .any(|wf| wf.workflow_id == wake_key.workflow_id)
1201
+ {
1202
+ continue;
1203
+ }
1204
+
1205
+ tx.delete(wake_key);
1206
+ }
1207
+
1208
+ let leased_workflow_ids = leased_workflows
1209
+ .iter()
1210
+ .map(|wf| wf.workflow_id)
1211
+ .collect::<Vec<_>>();
1212
+
1213
+ // Clear secondary indexes so that we don't get any new wake conditions inserted while
1214
+ // the workflow is running
1215
+ futures_util::stream::iter(leased_workflow_ids)
1216
+ .map(|workflow_id| {
1217
+ let tx = tx.clone();
1218
+ async move {
1219
+ // Clear sub workflow secondary idx
1220
+ let wake_sub_workflow_key =
1221
+ keys::workflow::WakeSubWorkflowKey::new(workflow_id);
1222
+ if let Some(entry) = tx
1223
+ .get(&self.subspace.pack(&wake_sub_workflow_key), Serializable)
1224
+ .await?
1225
+ {
1226
+ let sub_workflow_id =
1227
+ wake_sub_workflow_key.deserialize(&entry)?;
1228
+
1229
+ let sub_workflow_wake_key = keys::wake::SubWorkflowWakeKey::new(
1230
+ sub_workflow_id,
1231
+ workflow_id,
1232
+ );
1233
+
1234
+ tx.clear(&self.subspace.pack(&sub_workflow_wake_key));
1235
+ }
1236
+
1237
+ // Clear signals secondary index
1238
+ let wake_signals_subspace = self.subspace.subspace(
1239
+ &keys::workflow::WakeSignalKey::subspace(workflow_id),
1240
+ );
1241
+ tx.clear_subspace_range(&wake_signals_subspace);
1242
+
1243
+ anyhow::Ok(())
1244
+ }
1245
+ })
1246
+ // TODO: How to get rid of this buffer?
1247
+ .buffer_unordered(1024)
1248
+ .try_collect::<()>()
1249
+ .await?;
1250
+
1251
+ // NOTE: We don't read any workflow data in this txn since its only for acquiring leases.
1252
+ // The less operations we do in this txn the less contention there is with other workers.
1253
+ Ok(leased_workflows)
1254
+ }
1255
+ })
1256
+ .custom_instrument(tracing::info_span!("pull_workflows_tx"))
1257
+ .await
1258
+ .map_err(WorkflowError::Udb)?;
1259
+
1260
+ let worker_id_str = worker_id.to_string();
1261
+ let dt = start_instant.elapsed().as_secs_f64();
1262
+ metrics::LAST_PULL_WORKFLOWS_DURATION
1263
+ .record(dt, &[KeyValue::new("worker_id", worker_id_str.clone())]);
1264
+ metrics::PULL_WORKFLOWS_DURATION
1265
+ .record(dt, &[KeyValue::new("worker_id", worker_id_str.clone())]);
1266
+
1267
+ if leased_workflows.is_empty() {
1268
+ return Ok(Vec::new());
1269
+ }
1270
+
1271
+ let start_instant2 = Instant::now();
1272
+
1273
+ let pulled_workflows = self
1274
+ .pools
1275
+ .udb()
1276
+ .map_err(WorkflowError::PoolsGeneric)?
1277
+ .run(|tx| {
1278
+ let leased_workflows = leased_workflows.clone();
1279
+
1280
+ async move {
1281
+ // Read required wf data for each leased wf
1282
+ futures_util::stream::iter(leased_workflows)
1283
+ .map(|wf| {
1284
+ let tx = tx.clone();
1285
+ async move {
1286
+ let create_ts_key =
1287
+ keys::workflow::CreateTsKey::new(wf.workflow_id);
1288
+ let ray_id_key = keys::workflow::RayIdKey::new(wf.workflow_id);
1289
+ let input_key = keys::workflow::InputKey::new(wf.workflow_id);
1290
+ let state_key = keys::workflow::StateKey::new(wf.workflow_id);
1291
+ let input_subspace = self.subspace.subspace(&input_key);
1292
+ let state_subspace = self.subspace.subspace(&state_key);
1293
+ let active_history_subspace = self.subspace.subspace(
1294
+ &keys::history::HistorySubspaceKey::new(
1295
+ wf.workflow_id,
1296
+ keys::history::HistorySubspaceVariant::Active,
1297
+ ),
1298
+ );
1299
+
1300
+ let (
1301
+ create_ts_entry,
1302
+ ray_id_entry,
1303
+ input_chunks,
1304
+ state_chunks,
1305
+ events,
1306
+ ) = tokio::try_join!(
1307
+ async {
1308
+ tx.get(&self.subspace.pack(&create_ts_key), Serializable)
1309
+ .await
1310
+ },
1311
+ async {
1312
+ tx.get(&self.subspace.pack(&ray_id_key), Serializable).await
1313
+ },
1314
+ async {
1315
+ tx.get_ranges_keyvalues(
1316
+ universaldb::RangeOption {
1317
+ mode: StreamingMode::WantAll,
1318
+ ..(&input_subspace).into()
1319
+ },
1320
+ Serializable,
1321
+ )
1322
+ .try_collect::<Vec<_>>()
1323
+ .await
1324
+ },
1325
+ async {
1326
+ tx.get_ranges_keyvalues(
1327
+ universaldb::RangeOption {
1328
+ mode: StreamingMode::WantAll,
1329
+ ..(&state_subspace).into()
1330
+ },
1331
+ Serializable,
1332
+ )
1333
+ .try_collect::<Vec<_>>()
1334
+ .await
1335
+ },
1336
+ async {
1337
+ let mut events_by_location: HashMap<Location, Vec<Event>> =
1338
+ HashMap::new();
1339
+ let mut current_event =
1340
+ WorkflowHistoryEventBuilder::new(Location::empty());
1341
+
1342
+ let mut stream = tx.get_ranges_keyvalues(
1343
+ universaldb::RangeOption {
1344
+ mode: StreamingMode::WantAll,
1345
+ ..(&active_history_subspace).into()
1346
+ },
1347
+ Serializable,
1348
+ );
1349
+
1350
+ loop {
1351
+ let Some(entry) = stream.try_next().await? else {
1352
+ break;
1353
+ };
1354
+
1355
+ // Parse only the wf id and location of the current key
1356
+ let partial_key = self
1357
+ .subspace
1358
+ .unpack::<keys::history::PartialEventKey>(
1359
+ entry.key(),
1360
+ )?;
1361
+
1362
+ if current_event.location != partial_key.location {
1363
+ if current_event.location.is_empty() {
1364
+ current_event =
1365
+ WorkflowHistoryEventBuilder::new(
1366
+ partial_key.location,
1367
+ );
1368
+ } else {
1369
+ // Insert current event builder to into wf events and
1370
+ // reset state
1371
+ let previous_event = std::mem::replace(
1372
+ &mut current_event,
1373
+ WorkflowHistoryEventBuilder::new(
1374
+ partial_key.location,
1375
+ ),
1376
+ );
1377
+ events_by_location
1378
+ .entry(previous_event.location.root())
1379
+ .or_default()
1380
+ .push(Event::try_from(previous_event)?);
1381
+ }
1382
+ }
1383
+
1384
+ // Parse current key as any event key
1385
+ if let Ok(key) =
1386
+ self.subspace.unpack::<keys::history::EventTypeKey>(
1387
+ entry.key(),
1388
+ ) {
1389
+ let event_type = key.deserialize(entry.value())?;
1390
+
1391
+ current_event.event_type = Some(event_type);
1392
+ } else if let Ok(key) =
1393
+ self.subspace.unpack::<keys::history::VersionKey>(
1394
+ entry.key(),
1395
+ ) {
1396
+ let version = key.deserialize(entry.value())?;
1397
+
1398
+ current_event.version = Some(version);
1399
+ } else if let Ok(key) =
1400
+ self.subspace.unpack::<keys::history::CreateTsKey>(
1401
+ entry.key(),
1402
+ ) {
1403
+ let create_ts = key.deserialize(entry.value())?;
1404
+
1405
+ current_event.create_ts = Some(create_ts);
1406
+ } else if let Ok(key) =
1407
+ self.subspace
1408
+ .unpack::<keys::history::NameKey>(entry.key())
1409
+ {
1410
+ let name = key.deserialize(entry.value())?;
1411
+
1412
+ current_event.name = Some(name);
1413
+ } else if let Ok(key) =
1414
+ self.subspace.unpack::<keys::history::SignalIdKey>(
1415
+ entry.key(),
1416
+ ) {
1417
+ let signal_id = key.deserialize(entry.value())?;
1418
+
1419
+ current_event.signal_id = Some(signal_id);
1420
+ } else if let Ok(key) = self
1421
+ .subspace
1422
+ .unpack::<keys::history::SubWorkflowIdKey>(
1423
+ entry.key(),
1424
+ ) {
1425
+ let sub_workflow_id =
1426
+ key.deserialize(entry.value())?;
1427
+
1428
+ current_event.sub_workflow_id =
1429
+ Some(sub_workflow_id);
1430
+ } else if let Ok(_key) = self
1431
+ .subspace
1432
+ .unpack::<keys::history::InputChunkKey>(
1433
+ entry.key(),
1434
+ ) {
1435
+ current_event.input_chunks.push(entry);
1436
+ } else if let Ok(_key) = self
1437
+ .subspace
1438
+ .unpack::<keys::history::OutputChunkKey>(
1439
+ entry.key(),
1440
+ ) {
1441
+ current_event.output_chunks.push(entry);
1442
+ } else if let Ok(_key) =
1443
+ self.subspace
1444
+ .unpack::<keys::history::ErrorKey>(entry.key())
1445
+ {
1446
+ current_event.error_count += 1;
1447
+ } else if let Ok(key) =
1448
+ self.subspace.unpack::<keys::history::IterationKey>(
1449
+ entry.key(),
1450
+ ) {
1451
+ let iteration = key.deserialize(entry.value())?;
1452
+
1453
+ current_event.iteration = Some(iteration);
1454
+ } else if let Ok(key) = self
1455
+ .subspace
1456
+ .unpack::<keys::history::DeadlineTsKey>(
1457
+ entry.key(),
1458
+ ) {
1459
+ let deadline_ts = key.deserialize(entry.value())?;
1460
+
1461
+ current_event.deadline_ts = Some(deadline_ts);
1462
+ } else if let Ok(key) = self
1463
+ .subspace
1464
+ .unpack::<keys::history::SleepStateKey>(
1465
+ entry.key(),
1466
+ ) {
1467
+ let sleep_state = key.deserialize(entry.value())?;
1468
+
1469
+ current_event.sleep_state = Some(sleep_state);
1470
+ } else if let Ok(key) = self
1471
+ .subspace
1472
+ .unpack::<keys::history::InnerEventTypeKey>(
1473
+ entry.key(),
1474
+ ) {
1475
+ let inner_event_type =
1476
+ key.deserialize(entry.value())?;
1477
+
1478
+ current_event.inner_event_type =
1479
+ Some(inner_event_type);
1480
+ }
1481
+
1482
+ // We ignore keys we don't need (like tags)
1483
+ }
1484
+ // Insert final event
1485
+ if !current_event.location.is_empty() {
1486
+ events_by_location
1487
+ .entry(current_event.location.root())
1488
+ .or_default()
1489
+ .push(Event::try_from(current_event)?);
1490
+ }
1491
+
1492
+ Ok(events_by_location)
1493
+ }
1494
+ )?;
1495
+
1496
+ let create_ts = create_ts_key
1497
+ .deserialize(&create_ts_entry.context("key should exist")?)?;
1498
+ let ray_id = ray_id_key
1499
+ .deserialize(&ray_id_entry.context("key should exist")?)?;
1500
+ let input = input_key.combine(input_chunks)?;
1501
+ let state = if state_chunks.is_empty() {
1502
+ serde_json::value::RawValue::NULL.to_owned()
1503
+ } else {
1504
+ state_key.combine(state_chunks)?
1505
+ };
1506
+
1507
+ Result::<_>::Ok(PulledWorkflowData {
1508
+ workflow_id: wf.workflow_id,
1509
+ workflow_name: wf.workflow_name,
1510
+ create_ts,
1511
+ ray_id,
1512
+ input,
1513
+ state,
1514
+ wake_deadline_ts: wf.wake_deadline_ts,
1515
+ events,
1516
+ })
1517
+ }
1518
+ })
1519
+ // TODO: How to get rid of this buffer?
1520
+ .buffer_unordered(512)
1521
+ .try_collect::<Vec<_>>()
1522
+ .instrument(tracing::trace_span!("map_to_partial_workflow"))
1523
+ .await
1524
+ }
1525
+ })
1526
+ .custom_instrument(tracing::info_span!("pull_workflow_history_tx"))
1527
+ .await
1528
+ .map_err(WorkflowError::Udb)?;
1529
+
1530
+ let dt2 = start_instant2.elapsed().as_secs_f64();
1531
+ let dt = start_instant.elapsed().as_secs_f64();
1532
+ metrics::LAST_PULL_WORKFLOWS_FULL_DURATION
1533
+ .record(dt, &[KeyValue::new("worker_id", worker_id_str.clone())]);
1534
+ metrics::PULL_WORKFLOWS_FULL_DURATION
1535
+ .record(dt, &[KeyValue::new("worker_id", worker_id_str.clone())]);
1536
+ metrics::LAST_PULL_WORKFLOWS_HISTORY_DURATION.record(
1537
+ dt2 as u64,
1538
+ &[KeyValue::new("worker_id", worker_id_str.clone())],
1539
+ );
1540
+ metrics::PULL_WORKFLOWS_HISTORY_DURATION
1541
+ .record(dt2, &[KeyValue::new("worker_id", worker_id_str.clone())]);
1542
+
1543
+ Ok(pulled_workflows)
1544
+ }
1545
+
1546
+ #[tracing::instrument(skip_all)]
1547
+ async fn complete_workflow(
1548
+ &self,
1549
+ workflow_id: Id,
1550
+ workflow_name: &str,
1551
+ output: &serde_json::value::RawValue,
1552
+ ) -> WorkflowResult<()> {
1553
+ let start_instant = Instant::now();
1554
+
1555
+ let wrote_to_wake_idx = self
1556
+ .pools
1557
+ .udb()
1558
+ .map_err(WorkflowError::PoolsGeneric)?
1559
+ .run(|tx| {
1560
+ async move {
1561
+ let sub_workflow_wake_subspace = self
1562
+ .subspace
1563
+ .subspace(&keys::wake::SubWorkflowWakeKey::subspace(workflow_id));
1564
+ let tags_subspace = self
1565
+ .subspace
1566
+ .subspace(&keys::workflow::TagKey::subspace(workflow_id));
1567
+ let wake_deadline_key = keys::workflow::WakeDeadlineKey::new(workflow_id);
1568
+
1569
+ let mut stream = tx.get_ranges_keyvalues(
1570
+ universaldb::RangeOption {
1571
+ mode: StreamingMode::WantAll,
1572
+ ..(&sub_workflow_wake_subspace).into()
1573
+ },
1574
+ // NOTE: Must be Serializable to conflict with `get_sub_workflow`
1575
+ Serializable,
1576
+ );
1577
+
1578
+ let (wrote_to_wake_idx, tag_keys, wake_deadline_entry) = tokio::try_join!(
1579
+ // Check for other workflows waiting on this one, wake all
1580
+ async {
1581
+ let mut wrote_to_wake_idx = false;
1582
+
1583
+ while let Some(entry) = stream.try_next().await? {
1584
+ let sub_workflow_wake_key =
1585
+ self.subspace
1586
+ .unpack::<keys::wake::SubWorkflowWakeKey>(&entry.key())?;
1587
+ let workflow_name =
1588
+ sub_workflow_wake_key.deserialize(entry.value())?;
1589
+
1590
+ let wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
1591
+ workflow_name,
1592
+ sub_workflow_wake_key.workflow_id,
1593
+ keys::wake::WakeCondition::SubWorkflow {
1594
+ sub_workflow_id: workflow_id,
1595
+ },
1596
+ );
1597
+
1598
+ // Add wake condition for workflow
1599
+ tx.set(
1600
+ &self.subspace.pack(&wake_condition_key),
1601
+ &wake_condition_key.serialize(())?,
1602
+ );
1603
+
1604
+ // Clear secondary index
1605
+ tx.clear(entry.key());
1606
+
1607
+ wrote_to_wake_idx = true;
1608
+ }
1609
+
1610
+ Ok(wrote_to_wake_idx)
1611
+ },
1612
+ // Read tags
1613
+ tx.get_ranges_keyvalues(
1614
+ universaldb::RangeOption {
1615
+ mode: StreamingMode::WantAll,
1616
+ ..(&tags_subspace).into()
1617
+ },
1618
+ Serializable,
1619
+ )
1620
+ .map(|res| {
1621
+ self.subspace
1622
+ .unpack::<keys::workflow::TagKey>(res?.key())
1623
+ .map_err(anyhow::Error::from)
1624
+ })
1625
+ .try_collect::<Vec<_>>(),
1626
+ tx.get(&self.subspace.pack(&wake_deadline_key), Serializable),
1627
+ )?;
1628
+
1629
+ for key in tag_keys {
1630
+ let by_name_and_tag_key = keys::workflow::ByNameAndTagKey::new(
1631
+ workflow_name.to_string(),
1632
+ key.k,
1633
+ key.v,
1634
+ workflow_id,
1635
+ );
1636
+ tx.clear(&self.subspace.pack(&by_name_and_tag_key));
1637
+ }
1638
+
1639
+ // Clear null key
1640
+ {
1641
+ let by_name_and_tag_key = keys::workflow::ByNameAndTagKey::null(
1642
+ workflow_name.to_string(),
1643
+ workflow_id,
1644
+ );
1645
+ tx.clear(&self.subspace.pack(&by_name_and_tag_key));
1646
+ }
1647
+
1648
+ // Get and clear the pending deadline wake condition, if any. This could be put in the
1649
+ // `pull_workflows` function (where we clear secondary indexes) but we chose to clear it
1650
+ // here and in `commit_workflow` because its not a secondary index so theres no worry of
1651
+ // it inserting more wake conditions. This reduces the load on `pull_workflows`. The
1652
+ // reason this isn't immediately cleared in `pull_workflows` along with the rest of the
1653
+ // wake conditions is because it might be in the future.
1654
+ if let Some(raw) = wake_deadline_entry {
1655
+ let deadline_ts = wake_deadline_key.deserialize(&raw)?;
1656
+
1657
+ let wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
1658
+ workflow_name.to_string(),
1659
+ workflow_id,
1660
+ keys::wake::WakeCondition::Deadline { deadline_ts },
1661
+ );
1662
+
1663
+ tx.clear(&self.subspace.pack(&wake_condition_key));
1664
+ }
1665
+
1666
+ // Clear "has wake condition"
1667
+ let has_wake_condition_key =
1668
+ keys::workflow::HasWakeConditionKey::new(workflow_id);
1669
+ tx.clear(&self.subspace.pack(&has_wake_condition_key));
1670
+
1671
+ // Write output
1672
+ let output_key = keys::workflow::OutputKey::new(workflow_id);
1673
+
1674
+ for (i, chunk) in output_key.split_ref(output)?.into_iter().enumerate() {
1675
+ let chunk_key = output_key.chunk(i);
1676
+
1677
+ tx.set(&self.subspace.pack(&chunk_key), &chunk);
1678
+ }
1679
+
1680
+ // Clear lease
1681
+ let lease_key = keys::workflow::LeaseKey::new(workflow_id);
1682
+ tx.clear(&self.subspace.pack(&lease_key));
1683
+ let worker_id_key = keys::workflow::WorkerIdKey::new(workflow_id);
1684
+ tx.clear(&self.subspace.pack(&worker_id_key));
1685
+
1686
+ update_metric(
1687
+ &tx.with_subspace(self.subspace.clone()),
1688
+ Some(keys::metric::GaugeMetric::WorkflowActive(
1689
+ workflow_name.to_string(),
1690
+ )),
1691
+ Some(keys::metric::GaugeMetric::WorkflowComplete(
1692
+ workflow_name.to_string(),
1693
+ )),
1694
+ );
1695
+
1696
+ Ok(wrote_to_wake_idx)
1697
+ }
1698
+ })
1699
+ .custom_instrument(tracing::info_span!("complete_workflows_tx"))
1700
+ .await
1701
+ .map_err(WorkflowError::Udb)?;
1702
+
1703
+ // Wake worker again in case some other workflow was waiting for this one to complete
1704
+ if wrote_to_wake_idx {
1705
+ self.bump(BumpSubSubject::WorkflowComplete { workflow_id });
1706
+ self.bump(BumpSubSubject::Worker);
1707
+ }
1708
+
1709
+ let dt = start_instant.elapsed().as_secs_f64();
1710
+ metrics::COMPLETE_WORKFLOW_DURATION.record(
1711
+ dt,
1712
+ &[KeyValue::new("workflow_name", workflow_name.to_string())],
1713
+ );
1714
+
1715
+ Ok(())
1716
+ }
1717
+
1718
+ #[tracing::instrument(skip_all)]
1719
+ async fn commit_workflow(
1720
+ &self,
1721
+ workflow_id: Id,
1722
+ workflow_name: &str,
1723
+ wake_immediate: bool,
1724
+ wake_deadline_ts: Option<i64>,
1725
+ wake_signals: &[&str],
1726
+ wake_sub_workflow_id: Option<Id>,
1727
+ error: &str,
1728
+ ) -> WorkflowResult<()> {
1729
+ let start_instant = Instant::now();
1730
+
1731
+ self.pools
1732
+ .udb()
1733
+ .map_err(WorkflowError::PoolsGeneric)?
1734
+ .run(|tx| {
1735
+ async move {
1736
+ let wake_deadline_key = keys::workflow::WakeDeadlineKey::new(workflow_id);
1737
+
1738
+ let wake_deadline_entry = tx
1739
+ .get(&self.subspace.pack(&wake_deadline_key), Serializable)
1740
+ .await?;
1741
+
1742
+ // Add immediate wake for workflow
1743
+ if wake_immediate {
1744
+ let wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
1745
+ workflow_name.to_string(),
1746
+ workflow_id,
1747
+ keys::wake::WakeCondition::Immediate,
1748
+ );
1749
+ tx.set(
1750
+ &self.subspace.pack(&wake_condition_key),
1751
+ &wake_condition_key.serialize(())?,
1752
+ );
1753
+ }
1754
+
1755
+ // Get and clear the pending deadline wake condition, if any. This could be put in the
1756
+ // `pull_workflows` function (where we clear secondary indexes) but we chose to clear it
1757
+ // here and in `complete_workflow` because its not a secondary index so theres no worry of
1758
+ // it inserting more wake conditions. This reduces the load on `pull_workflows`. The
1759
+ // reason this isn't immediately cleared in `pull_workflows` along with the rest of the
1760
+ // wake conditions is because it might be in the future.
1761
+ if let Some(raw) = wake_deadline_entry {
1762
+ let deadline_ts = wake_deadline_key.deserialize(&raw)?;
1763
+
1764
+ let wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
1765
+ workflow_name.to_string(),
1766
+ workflow_id,
1767
+ keys::wake::WakeCondition::Deadline { deadline_ts },
1768
+ );
1769
+
1770
+ tx.clear(&self.subspace.pack(&wake_condition_key));
1771
+ }
1772
+
1773
+ // Write deadline wake index
1774
+ if let Some(deadline_ts) = wake_deadline_ts {
1775
+ let wake_condition_key = keys::wake::WorkflowWakeConditionKey::new(
1776
+ workflow_name.to_string(),
1777
+ workflow_id,
1778
+ keys::wake::WakeCondition::Deadline { deadline_ts },
1779
+ );
1780
+
1781
+ // Add wake condition for workflow
1782
+ tx.set(
1783
+ &self.subspace.pack(&wake_condition_key),
1784
+ &wake_condition_key.serialize(())?,
1785
+ );
1786
+
1787
+ // Write to wake deadline
1788
+ tx.set(
1789
+ &self.subspace.pack(&wake_deadline_key),
1790
+ &wake_deadline_key.serialize(deadline_ts)?,
1791
+ );
1792
+ }
1793
+
1794
+ self.write_signal_wake_idxs(workflow_id, wake_signals, &tx)?;
1795
+
1796
+ // Write sub workflow wake index
1797
+ if let Some(sub_workflow_id) = wake_sub_workflow_id {
1798
+ self.write_sub_workflow_wake_idx(
1799
+ workflow_id,
1800
+ workflow_name,
1801
+ sub_workflow_id,
1802
+ &tx,
1803
+ )?;
1804
+ }
1805
+
1806
+ // Update "has wake condition"
1807
+ let has_wake_condition_key =
1808
+ keys::workflow::HasWakeConditionKey::new(workflow_id);
1809
+ let has_wake_condition = wake_immediate
1810
+ || wake_deadline_ts.is_some()
1811
+ || !wake_signals.is_empty()
1812
+ || wake_sub_workflow_id.is_some();
1813
+ if has_wake_condition {
1814
+ tx.set(
1815
+ &self.subspace.pack(&has_wake_condition_key),
1816
+ &has_wake_condition_key.serialize(())?,
1817
+ );
1818
+ } else {
1819
+ tx.clear(&self.subspace.pack(&has_wake_condition_key));
1820
+ }
1821
+
1822
+ // Write error
1823
+ let error_key = keys::workflow::ErrorKey::new(workflow_id);
1824
+ tx.set(
1825
+ &self.subspace.pack(&error_key),
1826
+ &error_key.serialize(error.to_string())?,
1827
+ );
1828
+
1829
+ // Clear lease
1830
+ let lease_key = keys::workflow::LeaseKey::new(workflow_id);
1831
+ tx.clear(&self.subspace.pack(&lease_key));
1832
+ let worker_id_key = keys::workflow::WorkerIdKey::new(workflow_id);
1833
+ tx.clear(&self.subspace.pack(&worker_id_key));
1834
+
1835
+ update_metric(
1836
+ &tx.with_subspace(self.subspace.clone()),
1837
+ Some(keys::metric::GaugeMetric::WorkflowActive(
1838
+ workflow_name.to_string(),
1839
+ )),
1840
+ Some(if has_wake_condition {
1841
+ keys::metric::GaugeMetric::WorkflowSleeping(workflow_name.to_string())
1842
+ } else {
1843
+ keys::metric::GaugeMetric::WorkflowDead(
1844
+ workflow_name.to_string(),
1845
+ error.to_string(),
1846
+ )
1847
+ }),
1848
+ );
1849
+
1850
+ Ok(())
1851
+ }
1852
+ })
1853
+ .custom_instrument(tracing::info_span!("commit_workflow_tx"))
1854
+ .await
1855
+ .map_err(WorkflowError::Udb)?;
1856
+
1857
+ // Always wake the worker immediately again. This is an IMPORTANT implementation detail to prevent
1858
+ // race conditions with workflow sleep. Imagine the scenario:
1859
+ //
1860
+ // 1. workflow is between user code and commit
1861
+ // 2. worker reads wake condition for said workflow but cannot run it because it is already leased
1862
+ // 3. workflow commits
1863
+ //
1864
+ // This will result in the workflow sleeping instead of immediately running again.
1865
+ //
1866
+ // Adding this bump_workers call ensures that if the workflow has a valid wake condition before commit
1867
+ // then it will immediately wake up again.
1868
+ //
1869
+ // This is simpler than having this commit_workflow fn read wake conditions because:
1870
+ // - the wake conditions are not indexed by wf id
1871
+ // - would involve informing the worker to restart the workflow in memory instead of the usual
1872
+ // workflow lifecycle
1873
+ // - the worker is already designed to pull wake conditions frequently
1874
+ self.bump(BumpSubSubject::Worker);
1875
+
1876
+ let dt = start_instant.elapsed().as_secs_f64();
1877
+ metrics::COMMIT_WORKFLOW_DURATION.record(
1878
+ dt,
1879
+ &[KeyValue::new("workflow_name", workflow_name.to_string())],
1880
+ );
1881
+
1882
+ Ok(())
1883
+ }
1884
+
1885
+ #[tracing::instrument(skip_all)]
1886
+ async fn pull_next_signal(
1887
+ &self,
1888
+ workflow_id: Id,
1889
+ _workflow_name: &str,
1890
+ filter: &[&str],
1891
+ location: &Location,
1892
+ version: usize,
1893
+ _loop_location: Option<&Location>,
1894
+ last_try: bool,
1895
+ ) -> WorkflowResult<Option<SignalData>> {
1896
+ let owned_filter = filter
1897
+ .into_iter()
1898
+ .map(|x| x.to_string())
1899
+ .collect::<Vec<_>>();
1900
+
1901
+ // Fetch signal from UDB
1902
+ let signal =
1903
+ self.pools
1904
+ .udb()
1905
+ .map_err(WorkflowError::PoolsGeneric)?
1906
+ .run(|tx| {
1907
+ let owned_filter = owned_filter.clone();
1908
+
1909
+ async move {
1910
+ let signal = {
1911
+ // Create a stream for each signal name subspace
1912
+ let streams = owned_filter
1913
+ .iter()
1914
+ .map(|signal_name| {
1915
+ let pending_signal_subspace = self.subspace.subspace(
1916
+ &keys::workflow::PendingSignalKey::subspace(
1917
+ workflow_id,
1918
+ signal_name.to_string(),
1919
+ ),
1920
+ );
1921
+
1922
+ tx.get_ranges_keyvalues(
1923
+ universaldb::RangeOption {
1924
+ mode: StreamingMode::WantAll,
1925
+ limit: Some(1),
1926
+ ..(&pending_signal_subspace).into()
1927
+ },
1928
+ // NOTE: This is Serializable because any insert into this subspace
1929
+ // should cause a conflict and retry of this txn
1930
+ Serializable,
1931
+ )
1932
+ })
1933
+ .collect::<Vec<_>>();
1934
+
1935
+ // Fetch the next entry from all streams at the same time
1936
+ let mut results = futures_util::future::try_join_all(
1937
+ streams.into_iter().map(|mut stream| async move {
1938
+ if let Some(entry) = stream.try_next().await? {
1939
+ Result::<_>::Ok(Some((
1940
+ entry.key().to_vec(),
1941
+ self.subspace
1942
+ .unpack::<keys::workflow::PendingSignalKey>(
1943
+ &entry.key(),
1944
+ )?,
1945
+ )))
1946
+ } else {
1947
+ Ok(None)
1948
+ }
1949
+ }),
1950
+ )
1951
+ .instrument(tracing::trace_span!("map_signals"))
1952
+ .await?;
1953
+
1954
+ // Sort by ts
1955
+ results.sort_by_key(|res| res.as_ref().map(|(_, key)| key.ts));
1956
+
1957
+ results.into_iter().flatten().next().map(
1958
+ |(raw_key, pending_signal_key)| {
1959
+ (
1960
+ raw_key,
1961
+ pending_signal_key.signal_name,
1962
+ pending_signal_key.ts,
1963
+ pending_signal_key.signal_id,
1964
+ )
1965
+ },
1966
+ )
1967
+ };
1968
+
1969
+ // Signal found
1970
+ if let Some((raw_key, signal_name, ts, signal_id)) = signal {
1971
+ let ack_ts_key = keys::signal::AckTsKey::new(signal_id);
1972
+
1973
+ // Ack signal
1974
+ tx.add_conflict_range(
1975
+ &raw_key,
1976
+ &end_of_key_range(&raw_key),
1977
+ ConflictRangeType::Read,
1978
+ )?;
1979
+ tx.set(
1980
+ &self.subspace.pack(&ack_ts_key),
1981
+ &ack_ts_key.serialize(rivet_util::timestamp::now())?,
1982
+ );
1983
+
1984
+ update_metric(
1985
+ &tx.with_subspace(self.subspace.clone()),
1986
+ Some(keys::metric::GaugeMetric::SignalPending(
1987
+ signal_name.to_string(),
1988
+ )),
1989
+ None,
1990
+ );
1991
+
1992
+ // TODO: Split txn into two after acking here?
1993
+
1994
+ // Clear pending signal key
1995
+ tx.clear(&raw_key);
1996
+
1997
+ // Read signal body
1998
+ let body_key = keys::signal::BodyKey::new(signal_id);
1999
+ let body_subspace = self.subspace.subspace(&body_key);
2000
+
2001
+ let chunks = tx
2002
+ .get_ranges_keyvalues(
2003
+ universaldb::RangeOption {
2004
+ mode: StreamingMode::WantAll,
2005
+ ..(&body_subspace).into()
2006
+ },
2007
+ Serializable,
2008
+ )
2009
+ .try_collect::<Vec<_>>()
2010
+ .await?;
2011
+
2012
+ let body = body_key.combine(chunks)?;
2013
+
2014
+ // Insert history event
2015
+ keys::history::insert::signal_event(
2016
+ &self.subspace,
2017
+ &tx,
2018
+ workflow_id,
2019
+ &location,
2020
+ version,
2021
+ rivet_util::timestamp::now(),
2022
+ signal_id,
2023
+ &signal_name,
2024
+ &body,
2025
+ )?;
2026
+
2027
+ Ok(Some(SignalData {
2028
+ signal_id,
2029
+ signal_name,
2030
+ create_ts: ts,
2031
+ body,
2032
+ }))
2033
+ }
2034
+ // No signal found
2035
+ else {
2036
+ // Write signal wake index if no signal was received. Normally this is done in
2037
+ // `commit_workflow` but without this code there would be a race condition if the
2038
+ // signal is published between after this transaction and before `commit_workflow`.
2039
+ // There is a possibility of `commit_workflow` NOT writing a signal secondary index
2040
+ // after this in which case there might be an unnecessary wake condition inserted
2041
+ // causing the workflow to wake up again, but this is not as big of an issue because
2042
+ // workflow wakes should be idempotent if no events happen.
2043
+ // It is important that this is only written on the last try to pull workflows
2044
+ // (the workflow engine internally retries a few times) because it should only
2045
+ // write signal wake indexes before going to sleep (with err `NoSignalFound`) and
2046
+ // not during a retry.
2047
+ if last_try {
2048
+ self.write_signal_wake_idxs(
2049
+ workflow_id,
2050
+ &owned_filter.iter().map(|x| x.as_str()).collect::<Vec<_>>(),
2051
+ &tx,
2052
+ )?;
2053
+ }
2054
+
2055
+ Ok(None)
2056
+ }
2057
+ }
2058
+ })
2059
+ .custom_instrument(tracing::info_span!("pull_next_signal_tx"))
2060
+ .await
2061
+ .map_err(WorkflowError::Udb)?;
2062
+
2063
+ Ok(signal)
2064
+ }
2065
+
2066
+ #[tracing::instrument(skip_all)]
2067
+ async fn get_sub_workflow(
2068
+ &self,
2069
+ workflow_id: Id,
2070
+ workflow_name: &str,
2071
+ sub_workflow_id: Id,
2072
+ ) -> WorkflowResult<Option<WorkflowData>> {
2073
+ self.pools
2074
+ .udb()
2075
+ .map_err(WorkflowError::PoolsGeneric)?
2076
+ .run(|tx| {
2077
+ async move {
2078
+ let input_key = keys::workflow::InputKey::new(sub_workflow_id);
2079
+ let input_subspace = self.subspace.subspace(&input_key);
2080
+ let state_key = keys::workflow::StateKey::new(sub_workflow_id);
2081
+ let state_subspace = self.subspace.subspace(&state_key);
2082
+ let output_key = keys::workflow::OutputKey::new(sub_workflow_id);
2083
+ let output_subspace = self.subspace.subspace(&output_key);
2084
+ let has_wake_condition_key =
2085
+ keys::workflow::HasWakeConditionKey::new(sub_workflow_id);
2086
+
2087
+ // Read input and output
2088
+ let (input_chunks, state_chunks, output_chunks, has_wake_condition_entry) = tokio::try_join!(
2089
+ tx.get_ranges_keyvalues(
2090
+ universaldb::RangeOption {
2091
+ mode: StreamingMode::WantAll,
2092
+ ..(&input_subspace).into()
2093
+ },
2094
+ Serializable,
2095
+ )
2096
+ .try_collect::<Vec<_>>(),
2097
+ tx.get_ranges_keyvalues(
2098
+ universaldb::RangeOption {
2099
+ mode: StreamingMode::WantAll,
2100
+ ..(&state_subspace).into()
2101
+ },
2102
+ Serializable,
2103
+ )
2104
+ .try_collect::<Vec<_>>(),
2105
+ tx.get_ranges_keyvalues(
2106
+ universaldb::RangeOption {
2107
+ mode: StreamingMode::WantAll,
2108
+ ..(&output_subspace).into()
2109
+ },
2110
+ Serializable,
2111
+ )
2112
+ .try_collect::<Vec<_>>(),
2113
+ tx.get(&self.subspace.pack(&has_wake_condition_key), Serializable),
2114
+ )?;
2115
+
2116
+ if input_chunks.is_empty() {
2117
+ Ok(None)
2118
+ } else {
2119
+ let input = input_key.combine(input_chunks)?;
2120
+
2121
+ let state = if state_chunks.is_empty() {
2122
+ serde_json::value::RawValue::NULL.to_owned()
2123
+ } else {
2124
+ state_key.combine(state_chunks)?
2125
+ };
2126
+
2127
+ let output = if output_chunks.is_empty() {
2128
+ // Write sub workflow wake index if the sub workflow is not complete yet. Normally
2129
+ // this is done in `commit_workflow` but without this code there would be a race
2130
+ // condition if the sub workflow completes between after this transaction and
2131
+ // before `commit_workflow`. There is a possibility of `commit_workflow` NOT writing a
2132
+ // sub workflow secondary index after this in which case there might be an
2133
+ // unnecessary wake condition inserted causing the workflow to wake up again, but this
2134
+ // is not as big of an issue because workflow wakes should be idempotent if no events
2135
+ // happen.
2136
+ self.write_sub_workflow_wake_idx(
2137
+ workflow_id,
2138
+ workflow_name,
2139
+ sub_workflow_id,
2140
+ &tx,
2141
+ )?;
2142
+
2143
+ None
2144
+ } else {
2145
+ Some(output_key.combine(output_chunks)?)
2146
+ };
2147
+
2148
+ Ok(Some(WorkflowData {
2149
+ workflow_id: sub_workflow_id,
2150
+ input,
2151
+ state,
2152
+ output,
2153
+ has_wake_condition: has_wake_condition_entry.is_some(),
2154
+ }))
2155
+ }
2156
+ }
2157
+ })
2158
+ .custom_instrument(tracing::info_span!("get_sub_workflow_tx"))
2159
+ .await
2160
+ .map_err(WorkflowError::Udb)
2161
+ }
2162
+
2163
+ #[tracing::instrument(skip_all)]
2164
+ async fn publish_signal(
2165
+ &self,
2166
+ ray_id: Id,
2167
+ workflow_id: Id,
2168
+ signal_id: Id,
2169
+ signal_name: &str,
2170
+ body: &serde_json::value::RawValue,
2171
+ ) -> WorkflowResult<()> {
2172
+ self.pools
2173
+ .udb()
2174
+ .map_err(WorkflowError::PoolsGeneric)?
2175
+ .run(|tx| async move {
2176
+ self.publish_signal_inner(ray_id, workflow_id, signal_id, signal_name, body, &tx)
2177
+ .await
2178
+ })
2179
+ .custom_instrument(tracing::info_span!("publish_signal_tx"))
2180
+ .await
2181
+ .map_err(WorkflowError::Udb)?;
2182
+
2183
+ self.bump(BumpSubSubject::SignalPublish {
2184
+ to_workflow_id: workflow_id,
2185
+ });
2186
+ self.bump(BumpSubSubject::Worker);
2187
+
2188
+ Ok(())
2189
+ }
2190
+
2191
+ #[tracing::instrument(skip_all)]
2192
+ async fn publish_signal_from_workflow(
2193
+ &self,
2194
+ from_workflow_id: Id,
2195
+ location: &Location,
2196
+ version: usize,
2197
+ ray_id: Id,
2198
+ to_workflow_id: Id,
2199
+ signal_id: Id,
2200
+ signal_name: &str,
2201
+ body: &serde_json::value::RawValue,
2202
+ _loop_location: Option<&Location>,
2203
+ ) -> WorkflowResult<()> {
2204
+ self.pools
2205
+ .udb()
2206
+ .map_err(WorkflowError::PoolsGeneric)?
2207
+ .run(|tx| async move {
2208
+ self.publish_signal_inner(
2209
+ ray_id,
2210
+ to_workflow_id,
2211
+ signal_id,
2212
+ signal_name,
2213
+ body,
2214
+ &tx,
2215
+ )
2216
+ .await?;
2217
+
2218
+ // Insert history event
2219
+ keys::history::insert::signal_send_event(
2220
+ &self.subspace,
2221
+ &tx,
2222
+ from_workflow_id,
2223
+ &location,
2224
+ version,
2225
+ rivet_util::timestamp::now(),
2226
+ signal_id,
2227
+ &signal_name,
2228
+ &body,
2229
+ to_workflow_id,
2230
+ )?;
2231
+
2232
+ Ok(())
2233
+ })
2234
+ .custom_instrument(tracing::info_span!("publish_signal_from_workflow_tx"))
2235
+ .await
2236
+ .map_err(WorkflowError::Udb)?;
2237
+
2238
+ self.bump(BumpSubSubject::SignalPublish { to_workflow_id });
2239
+ self.bump(BumpSubSubject::Worker);
2240
+
2241
+ Ok(())
2242
+ }
2243
+
2244
+ #[tracing::instrument(skip_all, fields(%sub_workflow_id, %sub_workflow_name, unique))]
2245
+ async fn dispatch_sub_workflow(
2246
+ &self,
2247
+ ray_id: Id,
2248
+ from_workflow_id: Id,
2249
+ location: &Location,
2250
+ version: usize,
2251
+ sub_workflow_id: Id,
2252
+ sub_workflow_name: &str,
2253
+ tags: Option<&serde_json::Value>,
2254
+ input: &serde_json::value::RawValue,
2255
+ _loop_location: Option<&Location>,
2256
+ unique: bool,
2257
+ ) -> WorkflowResult<Id> {
2258
+ let sub_workflow_id = self
2259
+ .pools
2260
+ .udb()
2261
+ .map_err(WorkflowError::PoolsGeneric)?
2262
+ .run(|tx| async move {
2263
+ let sub_workflow_id = self
2264
+ .dispatch_workflow_inner(
2265
+ ray_id,
2266
+ sub_workflow_id,
2267
+ sub_workflow_name,
2268
+ tags,
2269
+ input,
2270
+ unique,
2271
+ &tx,
2272
+ )
2273
+ .await?;
2274
+
2275
+ // Insert history event
2276
+ keys::history::insert::sub_workflow_event(
2277
+ &self.subspace,
2278
+ &tx,
2279
+ from_workflow_id,
2280
+ &location,
2281
+ version,
2282
+ rivet_util::timestamp::now(),
2283
+ sub_workflow_id,
2284
+ sub_workflow_name,
2285
+ tags,
2286
+ input,
2287
+ )?;
2288
+
2289
+ Ok(sub_workflow_id)
2290
+ })
2291
+ .custom_instrument(tracing::info_span!("dispatch_sub_workflow_tx"))
2292
+ .await
2293
+ .map_err(WorkflowError::Udb)?;
2294
+
2295
+ self.bump(BumpSubSubject::Worker);
2296
+
2297
+ Ok(sub_workflow_id)
2298
+ }
2299
+
2300
+ #[tracing::instrument(skip_all)]
2301
+ async fn update_workflow_tags(
2302
+ &self,
2303
+ workflow_id: Id,
2304
+ workflow_name: &str,
2305
+ tags: &serde_json::Value,
2306
+ ) -> WorkflowResult<()> {
2307
+ self.pools
2308
+ .udb()
2309
+ .map_err(WorkflowError::PoolsGeneric)?
2310
+ .run(|tx| {
2311
+ async move {
2312
+ let tags_subspace = self
2313
+ .subspace
2314
+ .subspace(&keys::workflow::TagKey::subspace(workflow_id));
2315
+
2316
+ // Read old tags
2317
+ let tag_keys = tx
2318
+ .get_ranges_keyvalues(
2319
+ universaldb::RangeOption {
2320
+ mode: StreamingMode::WantAll,
2321
+ ..(&tags_subspace).into()
2322
+ },
2323
+ Serializable,
2324
+ )
2325
+ .map(|res| {
2326
+ self.subspace
2327
+ .unpack::<keys::workflow::TagKey>(res?.key())
2328
+ .map_err(anyhow::Error::from)
2329
+ })
2330
+ .try_collect::<Vec<_>>()
2331
+ .await?;
2332
+
2333
+ // Clear old tags
2334
+ tx.clear_subspace_range(&tags_subspace);
2335
+
2336
+ // Clear old "by name and first tag" secondary index
2337
+ for key in tag_keys {
2338
+ keys::workflow::ByNameAndTagKey::new(
2339
+ workflow_name.to_string(),
2340
+ key.k,
2341
+ key.v,
2342
+ workflow_id,
2343
+ );
2344
+ }
2345
+
2346
+ // Write new tags
2347
+ let tags = tags
2348
+ .as_object()
2349
+ .ok_or_else(|| WorkflowError::InvalidTags("must be an object".to_string()))?
2350
+ .into_iter()
2351
+ .map(|(k, v)| Ok((k.clone(), value_to_str(v)?)))
2352
+ .collect::<WorkflowResult<Vec<_>>>()?;
2353
+
2354
+ for (k, v) in &tags {
2355
+ let tag_key =
2356
+ keys::workflow::TagKey::new(workflow_id, k.clone(), v.clone());
2357
+ tx.set(&self.subspace.pack(&tag_key), &tag_key.serialize(())?);
2358
+
2359
+ // Write new "by name and first tag" secondary index
2360
+ let by_name_and_tag_key = keys::workflow::ByNameAndTagKey::new(
2361
+ workflow_name.to_string(),
2362
+ k.clone(),
2363
+ v.clone(),
2364
+ workflow_id,
2365
+ );
2366
+ let rest_of_tags = tags
2367
+ .iter()
2368
+ .filter(|(k2, _)| k2 != k)
2369
+ .map(|(k, v)| (k.clone(), v.clone()))
2370
+ .collect();
2371
+ tx.set(
2372
+ &self.subspace.pack(&by_name_and_tag_key),
2373
+ &by_name_and_tag_key.serialize(rest_of_tags)?,
2374
+ );
2375
+ }
2376
+
2377
+ Ok(())
2378
+ }
2379
+ })
2380
+ .custom_instrument(tracing::info_span!("update_workflow_tags_tx"))
2381
+ .await
2382
+ .map_err(WorkflowError::Udb)?;
2383
+
2384
+ Ok(())
2385
+ }
2386
+
2387
+ #[tracing::instrument(skip_all)]
2388
+ async fn update_workflow_state(
2389
+ &self,
2390
+ workflow_id: Id,
2391
+ state: &serde_json::value::RawValue,
2392
+ ) -> WorkflowResult<()> {
2393
+ self.pools
2394
+ .udb()
2395
+ .map_err(WorkflowError::PoolsGeneric)?
2396
+ .run(|tx| {
2397
+ async move {
2398
+ let state_key = keys::workflow::StateKey::new(workflow_id);
2399
+ let state_subspace = self.subspace.subspace(&state_key);
2400
+
2401
+ // Clear old state
2402
+ tx.clear_subspace_range(&state_subspace);
2403
+
2404
+ // Write new state
2405
+ for (i, chunk) in state_key.split_ref(&state)?.into_iter().enumerate() {
2406
+ let chunk_key = state_key.chunk(i);
2407
+
2408
+ tx.set(&self.subspace.pack(&chunk_key), &chunk);
2409
+ }
2410
+
2411
+ Ok(())
2412
+ }
2413
+ })
2414
+ .custom_instrument(tracing::info_span!("update_workflow_state_tx"))
2415
+ .await
2416
+ .map_err(WorkflowError::Udb)?;
2417
+
2418
+ Ok(())
2419
+ }
2420
+
2421
+ #[tracing::instrument(skip_all)]
2422
+ async fn commit_workflow_activity_event(
2423
+ &self,
2424
+ from_workflow_id: Id,
2425
+ location: &Location,
2426
+ version: usize,
2427
+ name: &str,
2428
+ create_ts: i64,
2429
+ input: &serde_json::value::RawValue,
2430
+ res: Result<&serde_json::value::RawValue, &str>,
2431
+ _loop_location: Option<&Location>,
2432
+ ) -> WorkflowResult<()> {
2433
+ self.pools
2434
+ .udb()
2435
+ .map_err(WorkflowError::PoolsGeneric)?
2436
+ .run(|tx| async move {
2437
+ keys::history::insert::activity_event(
2438
+ &self.subspace,
2439
+ &tx,
2440
+ from_workflow_id,
2441
+ location,
2442
+ version,
2443
+ create_ts,
2444
+ name,
2445
+ input,
2446
+ res,
2447
+ )?;
2448
+
2449
+ Ok(())
2450
+ })
2451
+ .custom_instrument(tracing::info_span!("commit_workflow_activity_event_tx"))
2452
+ .await
2453
+ .map_err(WorkflowError::Udb)?;
2454
+
2455
+ Ok(())
2456
+ }
2457
+
2458
+ #[tracing::instrument(skip_all)]
2459
+ async fn commit_workflow_message_send_event(
2460
+ &self,
2461
+ from_workflow_id: Id,
2462
+ location: &Location,
2463
+ version: usize,
2464
+ tags: &serde_json::Value,
2465
+ message_name: &str,
2466
+ body: &serde_json::value::RawValue,
2467
+ _loop_location: Option<&Location>,
2468
+ ) -> WorkflowResult<()> {
2469
+ self.pools
2470
+ .udb()
2471
+ .map_err(WorkflowError::PoolsGeneric)?
2472
+ .run(|tx| async move {
2473
+ keys::history::insert::message_send_event(
2474
+ &self.subspace,
2475
+ &tx,
2476
+ from_workflow_id,
2477
+ location,
2478
+ version,
2479
+ rivet_util::timestamp::now(),
2480
+ tags,
2481
+ message_name,
2482
+ body,
2483
+ )?;
2484
+
2485
+ Ok(())
2486
+ })
2487
+ .custom_instrument(tracing::info_span!("commit_workflow_message_send_event_tx"))
2488
+ .await
2489
+ .map_err(WorkflowError::Udb)?;
2490
+
2491
+ Ok(())
2492
+ }
2493
+
2494
+ #[tracing::instrument(skip_all)]
2495
+ async fn upsert_workflow_loop_event(
2496
+ &self,
2497
+ from_workflow_id: Id,
2498
+ _workflow_name: &str,
2499
+ location: &Location,
2500
+ version: usize,
2501
+ iteration: usize,
2502
+ state: &serde_json::value::RawValue,
2503
+ output: Option<&serde_json::value::RawValue>,
2504
+ _loop_location: Option<&Location>,
2505
+ ) -> WorkflowResult<()> {
2506
+ self.pools
2507
+ .udb()
2508
+ .map_err(WorkflowError::PoolsGeneric)?
2509
+ .run(|tx| async move {
2510
+ if iteration == 0 {
2511
+ keys::history::insert::loop_event(
2512
+ &self.subspace,
2513
+ &tx,
2514
+ from_workflow_id,
2515
+ location,
2516
+ version,
2517
+ rivet_util::timestamp::now(),
2518
+ iteration,
2519
+ state,
2520
+ output,
2521
+ )?;
2522
+ } else {
2523
+ keys::history::insert::update_loop_event(
2524
+ &self.subspace,
2525
+ &tx,
2526
+ from_workflow_id,
2527
+ location,
2528
+ iteration,
2529
+ state,
2530
+ output,
2531
+ )?;
2532
+
2533
+ let active_history_subspace =
2534
+ self.subspace
2535
+ .subspace(&keys::history::HistorySubspaceKey::new(
2536
+ from_workflow_id,
2537
+ keys::history::HistorySubspaceVariant::Active,
2538
+ ));
2539
+
2540
+ let forgotten_history_subspace =
2541
+ self.subspace
2542
+ .subspace(&keys::history::HistorySubspaceKey::new(
2543
+ from_workflow_id,
2544
+ keys::history::HistorySubspaceVariant::Forgotten,
2545
+ ));
2546
+
2547
+ let loop_events_subspace =
2548
+ self.subspace
2549
+ .subspace(&keys::history::EventHistorySubspaceKey::entire(
2550
+ from_workflow_id,
2551
+ location.clone(),
2552
+ false,
2553
+ ));
2554
+
2555
+ let mut stream = tx.get_ranges_keyvalues(
2556
+ universaldb::RangeOption {
2557
+ mode: StreamingMode::WantAll,
2558
+ ..(&loop_events_subspace).into()
2559
+ },
2560
+ Serializable,
2561
+ );
2562
+
2563
+ // Move all current events under this loop to the forgotten history
2564
+ loop {
2565
+ let Some(entry) = stream.try_next().await? else {
2566
+ break;
2567
+ };
2568
+
2569
+ if !active_history_subspace.is_start_of(entry.key()) {
2570
+ return Err(universaldb::tuple::PackError::BadPrefix.into());
2571
+ }
2572
+
2573
+ // Truncate tuple up to ACTIVE and replace it with FORGOTTEN
2574
+ let truncated_key = &entry.key()[active_history_subspace.bytes().len()..];
2575
+ let forgotten_key =
2576
+ [forgotten_history_subspace.bytes(), truncated_key].concat();
2577
+
2578
+ tx.set(&forgotten_key, entry.value());
2579
+ }
2580
+
2581
+ tx.clear_subspace_range(&loop_events_subspace);
2582
+
2583
+ // Only retain last 100 events in forgotten history
2584
+ if iteration > 100 {
2585
+ let old_forgotten_subspace_start =
2586
+ self.subspace
2587
+ .pack(&keys::history::EventHistorySubspaceKey::new(
2588
+ from_workflow_id,
2589
+ location.clone(),
2590
+ 0,
2591
+ true,
2592
+ ));
2593
+ let old_forgotten_subspace_end =
2594
+ self.subspace
2595
+ .pack(&keys::history::EventHistorySubspaceKey::new(
2596
+ from_workflow_id,
2597
+ location.clone(),
2598
+ iteration - 100,
2599
+ true,
2600
+ ));
2601
+
2602
+ tx.clear_range(&old_forgotten_subspace_start, &old_forgotten_subspace_end);
2603
+ }
2604
+ }
2605
+
2606
+ Ok(())
2607
+ })
2608
+ .custom_instrument(tracing::info_span!("upsert_loop_event_tx"))
2609
+ .await
2610
+ .map_err(WorkflowError::Udb)?;
2611
+
2612
+ Ok(())
2613
+ }
2614
+
2615
+ #[tracing::instrument(skip_all)]
2616
+ async fn commit_workflow_sleep_event(
2617
+ &self,
2618
+ from_workflow_id: Id,
2619
+ location: &Location,
2620
+ version: usize,
2621
+ deadline_ts: i64,
2622
+ _loop_location: Option<&Location>,
2623
+ ) -> WorkflowResult<()> {
2624
+ self.pools
2625
+ .udb()
2626
+ .map_err(WorkflowError::PoolsGeneric)?
2627
+ .run(|tx| async move {
2628
+ keys::history::insert::sleep_event(
2629
+ &self.subspace,
2630
+ &tx,
2631
+ from_workflow_id,
2632
+ location,
2633
+ version,
2634
+ rivet_util::timestamp::now(),
2635
+ deadline_ts,
2636
+ SleepState::Normal,
2637
+ )?;
2638
+
2639
+ Ok(())
2640
+ })
2641
+ .custom_instrument(tracing::info_span!("commit_workflow_sleep_event_tx"))
2642
+ .await
2643
+ .map_err(WorkflowError::Udb)?;
2644
+
2645
+ Ok(())
2646
+ }
2647
+
2648
+ #[tracing::instrument(skip_all)]
2649
+ async fn update_workflow_sleep_event_state(
2650
+ &self,
2651
+ from_workflow_id: Id,
2652
+ location: &Location,
2653
+ state: SleepState,
2654
+ ) -> WorkflowResult<()> {
2655
+ self.pools
2656
+ .udb()
2657
+ .map_err(WorkflowError::PoolsGeneric)?
2658
+ .run(|tx| async move {
2659
+ keys::history::insert::update_sleep_event(
2660
+ &self.subspace,
2661
+ &tx,
2662
+ from_workflow_id,
2663
+ location,
2664
+ state,
2665
+ )?;
2666
+
2667
+ Ok(())
2668
+ })
2669
+ .custom_instrument(tracing::info_span!("update_workflow_sleep_state_tx"))
2670
+ .await
2671
+ .map_err(WorkflowError::Udb)?;
2672
+
2673
+ Ok(())
2674
+ }
2675
+
2676
+ #[tracing::instrument(skip_all)]
2677
+ async fn commit_workflow_branch_event(
2678
+ &self,
2679
+ from_workflow_id: Id,
2680
+ location: &Location,
2681
+ version: usize,
2682
+ _loop_location: Option<&Location>,
2683
+ ) -> WorkflowResult<()> {
2684
+ self.pools
2685
+ .udb()
2686
+ .map_err(WorkflowError::PoolsGeneric)?
2687
+ .run(|tx| async move {
2688
+ keys::history::insert::branch_event(
2689
+ &self.subspace,
2690
+ &tx,
2691
+ from_workflow_id,
2692
+ location,
2693
+ version,
2694
+ rivet_util::timestamp::now(),
2695
+ )?;
2696
+
2697
+ Ok(())
2698
+ })
2699
+ .custom_instrument(tracing::info_span!("commit_workflow_branch_event_tx"))
2700
+ .await
2701
+ .map_err(WorkflowError::Udb)?;
2702
+
2703
+ Ok(())
2704
+ }
2705
+
2706
+ #[tracing::instrument(skip_all)]
2707
+ async fn commit_workflow_removed_event(
2708
+ &self,
2709
+ from_workflow_id: Id,
2710
+ location: &Location,
2711
+ event_type: EventType,
2712
+ event_name: Option<&str>,
2713
+ _loop_location: Option<&Location>,
2714
+ ) -> WorkflowResult<()> {
2715
+ self.pools
2716
+ .udb()
2717
+ .map_err(WorkflowError::PoolsGeneric)?
2718
+ .run(|tx| async move {
2719
+ keys::history::insert::removed_event(
2720
+ &self.subspace,
2721
+ &tx,
2722
+ from_workflow_id,
2723
+ location,
2724
+ 1, // Default
2725
+ rivet_util::timestamp::now(),
2726
+ event_type,
2727
+ event_name,
2728
+ )?;
2729
+
2730
+ Ok(())
2731
+ })
2732
+ .custom_instrument(tracing::info_span!("commit_workflow_removed_event_tx"))
2733
+ .await
2734
+ .map_err(WorkflowError::Udb)?;
2735
+
2736
+ Ok(())
2737
+ }
2738
+
2739
+ #[tracing::instrument(skip_all)]
2740
+ async fn commit_workflow_version_check_event(
2741
+ &self,
2742
+ from_workflow_id: Id,
2743
+ location: &Location,
2744
+ version: usize,
2745
+ _loop_location: Option<&Location>,
2746
+ ) -> WorkflowResult<()> {
2747
+ self.pools
2748
+ .udb()
2749
+ .map_err(WorkflowError::PoolsGeneric)?
2750
+ .run(|tx| async move {
2751
+ keys::history::insert::version_check_event(
2752
+ &self.subspace,
2753
+ &tx,
2754
+ from_workflow_id,
2755
+ location,
2756
+ version,
2757
+ rivet_util::timestamp::now(),
2758
+ )?;
2759
+
2760
+ Ok(())
2761
+ })
2762
+ .custom_instrument(tracing::info_span!(
2763
+ "commit_workflow_version_check_event_tx"
2764
+ ))
2765
+ .await
2766
+ .map_err(WorkflowError::Udb)?;
2767
+
2768
+ Ok(())
2769
+ }
2770
+ }
2771
+
2772
+ #[derive(Debug, Clone)]
2773
+ struct MinimalPulledWorkflow {
2774
+ workflow_id: Id,
2775
+ workflow_name: String,
2776
+ wake_deadline_ts: Option<i64>,
2777
+ earliest_wake_condition_ts: i64,
2778
+ }
2779
+
2780
+ fn update_metric(
2781
+ tx: &universaldb::Transaction,
2782
+ previous: Option<keys::metric::GaugeMetric>,
2783
+ current: Option<keys::metric::GaugeMetric>,
2784
+ ) {
2785
+ if &previous == &current {
2786
+ return;
2787
+ }
2788
+
2789
+ if let Some(previous) = previous {
2790
+ tx.atomic_op(
2791
+ &keys::metric::GaugeMetricKey::new(previous),
2792
+ &(-1isize).to_le_bytes(),
2793
+ MutationType::Add,
2794
+ );
2795
+ }
2796
+
2797
+ if let Some(current) = current {
2798
+ tx.atomic_op(
2799
+ &keys::metric::GaugeMetricKey::new(current),
2800
+ &1usize.to_le_bytes(),
2801
+ MutationType::Add,
2802
+ );
2803
+ }
2804
+ }
2805
+
2806
+ struct WorkflowHistoryEventBuilder {
2807
+ location: Location,
2808
+ event_type: Option<EventType>,
2809
+ version: Option<usize>,
2810
+ create_ts: Option<i64>,
2811
+ name: Option<String>,
2812
+ signal_id: Option<Id>,
2813
+ sub_workflow_id: Option<Id>,
2814
+ input_chunks: Vec<Value>,
2815
+ output_chunks: Vec<Value>,
2816
+ error_count: usize,
2817
+ iteration: Option<usize>,
2818
+ deadline_ts: Option<i64>,
2819
+ sleep_state: Option<SleepState>,
2820
+ inner_event_type: Option<EventType>,
2821
+ }
2822
+
2823
+ impl WorkflowHistoryEventBuilder {
2824
+ fn new(location: Location) -> Self {
2825
+ WorkflowHistoryEventBuilder {
2826
+ location,
2827
+ event_type: None,
2828
+ version: None,
2829
+ create_ts: None,
2830
+ name: None,
2831
+ signal_id: None,
2832
+ sub_workflow_id: None,
2833
+ input_chunks: Vec::new(),
2834
+ output_chunks: Vec::new(),
2835
+ error_count: 0,
2836
+ iteration: None,
2837
+ deadline_ts: None,
2838
+ sleep_state: None,
2839
+ inner_event_type: None,
2840
+ }
2841
+ }
2842
+ }
2843
+
2844
+ impl TryFrom<WorkflowHistoryEventBuilder> for Event {
2845
+ type Error = WorkflowError;
2846
+
2847
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2848
+ let event_type = value
2849
+ .event_type
2850
+ .ok_or(WorkflowError::MissingEventData("event_type"))?;
2851
+
2852
+ Ok(Event {
2853
+ coordinate: value
2854
+ .location
2855
+ .tail()
2856
+ .cloned()
2857
+ .ok_or(WorkflowError::MissingEventData("location"))?,
2858
+ version: value
2859
+ .version
2860
+ .ok_or(WorkflowError::MissingEventData("version"))?,
2861
+ data: match event_type {
2862
+ EventType::Activity => EventData::Activity(value.try_into()?),
2863
+ EventType::Signal => EventData::Signal(value.try_into()?),
2864
+ EventType::SignalSend => EventData::SignalSend(value.try_into()?),
2865
+ EventType::MessageSend => EventData::MessageSend(value.try_into()?),
2866
+ EventType::SubWorkflow => EventData::SubWorkflow(value.try_into()?),
2867
+ EventType::Loop => EventData::Loop(value.try_into()?),
2868
+ EventType::Sleep => EventData::Sleep(value.try_into()?),
2869
+ EventType::Branch => EventData::Branch,
2870
+ EventType::Removed => EventData::Removed(value.try_into()?),
2871
+ EventType::VersionCheck => EventData::VersionCheck,
2872
+ },
2873
+ })
2874
+ }
2875
+ }
2876
+
2877
+ impl TryFrom<WorkflowHistoryEventBuilder> for ActivityEvent {
2878
+ type Error = WorkflowError;
2879
+
2880
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2881
+ Ok(ActivityEvent {
2882
+ name: value.name.ok_or(WorkflowError::MissingEventData("name"))?,
2883
+ create_ts: value
2884
+ .create_ts
2885
+ .ok_or(WorkflowError::MissingEventData("create_ts"))?,
2886
+ output: {
2887
+ if value.output_chunks.is_empty() {
2888
+ None
2889
+ } else {
2890
+ // workflow_id not needed
2891
+ let output_key = keys::history::OutputKey::new(Id::nil(), value.location);
2892
+ Some(
2893
+ output_key
2894
+ .combine(value.output_chunks)
2895
+ .map_err(WorkflowError::DeserializeEventData)?,
2896
+ )
2897
+ }
2898
+ },
2899
+ error_count: value.error_count,
2900
+ })
2901
+ }
2902
+ }
2903
+
2904
+ impl TryFrom<WorkflowHistoryEventBuilder> for SignalEvent {
2905
+ type Error = WorkflowError;
2906
+
2907
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2908
+ Ok(SignalEvent {
2909
+ name: value.name.ok_or(WorkflowError::MissingEventData("name"))?,
2910
+ body: {
2911
+ if value.input_chunks.is_empty() {
2912
+ return Err(WorkflowError::MissingEventData("input"));
2913
+ } else {
2914
+ // workflow_id not needed
2915
+ let input_key = keys::history::InputKey::new(Id::nil(), value.location);
2916
+ input_key
2917
+ .combine(value.input_chunks)
2918
+ .map_err(WorkflowError::DeserializeEventData)?
2919
+ }
2920
+ },
2921
+ })
2922
+ }
2923
+ }
2924
+
2925
+ impl TryFrom<WorkflowHistoryEventBuilder> for SignalSendEvent {
2926
+ type Error = WorkflowError;
2927
+
2928
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2929
+ Ok(SignalSendEvent {
2930
+ signal_id: value
2931
+ .signal_id
2932
+ .ok_or(WorkflowError::MissingEventData("signal_id"))?,
2933
+ name: value.name.ok_or(WorkflowError::MissingEventData("name"))?,
2934
+ })
2935
+ }
2936
+ }
2937
+
2938
+ impl TryFrom<WorkflowHistoryEventBuilder> for MessageSendEvent {
2939
+ type Error = WorkflowError;
2940
+
2941
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2942
+ Ok(MessageSendEvent {
2943
+ name: value.name.ok_or(WorkflowError::MissingEventData("name"))?,
2944
+ })
2945
+ }
2946
+ }
2947
+
2948
+ impl TryFrom<WorkflowHistoryEventBuilder> for SubWorkflowEvent {
2949
+ type Error = WorkflowError;
2950
+
2951
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2952
+ Ok(SubWorkflowEvent {
2953
+ sub_workflow_id: value
2954
+ .sub_workflow_id
2955
+ .ok_or(WorkflowError::MissingEventData("sub_workflow_id"))?,
2956
+ name: value.name.ok_or(WorkflowError::MissingEventData("name"))?,
2957
+ })
2958
+ }
2959
+ }
2960
+
2961
+ impl TryFrom<WorkflowHistoryEventBuilder> for LoopEvent {
2962
+ type Error = WorkflowError;
2963
+
2964
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
2965
+ Ok(LoopEvent {
2966
+ state: {
2967
+ if value.input_chunks.is_empty() {
2968
+ return Err(WorkflowError::MissingEventData("input"));
2969
+ } else {
2970
+ // workflow_id not needed
2971
+ let input_key = keys::history::InputKey::new(Id::nil(), value.location.clone());
2972
+ input_key
2973
+ .combine(value.input_chunks)
2974
+ .map_err(WorkflowError::DeserializeEventData)?
2975
+ }
2976
+ },
2977
+ output: {
2978
+ if value.output_chunks.is_empty() {
2979
+ None
2980
+ } else {
2981
+ // workflow_id not needed
2982
+ let output_key = keys::history::OutputKey::new(Id::nil(), value.location);
2983
+ Some(
2984
+ output_key
2985
+ .combine(value.output_chunks)
2986
+ .map_err(WorkflowError::DeserializeEventData)?,
2987
+ )
2988
+ }
2989
+ },
2990
+ iteration: value
2991
+ .iteration
2992
+ .ok_or(WorkflowError::MissingEventData("iteration"))?
2993
+ .try_into()
2994
+ .map_err(|_| WorkflowError::IntegerConversion)?,
2995
+ })
2996
+ }
2997
+ }
2998
+
2999
+ impl TryFrom<WorkflowHistoryEventBuilder> for SleepEvent {
3000
+ type Error = WorkflowError;
3001
+
3002
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
3003
+ Ok(SleepEvent {
3004
+ deadline_ts: value
3005
+ .deadline_ts
3006
+ .ok_or(WorkflowError::MissingEventData("deadline_ts"))?,
3007
+ state: value
3008
+ .sleep_state
3009
+ .ok_or(WorkflowError::MissingEventData("sleep_state"))?,
3010
+ })
3011
+ }
3012
+ }
3013
+
3014
+ impl TryFrom<WorkflowHistoryEventBuilder> for RemovedEvent {
3015
+ type Error = WorkflowError;
3016
+
3017
+ fn try_from(value: WorkflowHistoryEventBuilder) -> WorkflowResult<Self> {
3018
+ Ok(RemovedEvent {
3019
+ name: value.name,
3020
+ event_type: value
3021
+ .inner_event_type
3022
+ .ok_or(WorkflowError::MissingEventData("inner_event_type"))?,
3023
+ })
3024
+ }
3025
+ }
3026
+
3027
+ fn value_to_str(v: &serde_json::Value) -> WorkflowResult<String> {
3028
+ match v {
3029
+ serde_json::Value::String(s) => Ok(s.clone()),
3030
+ _ => cjson::to_string(&v).map_err(WorkflowError::CjsonSerializeTags),
3031
+ }
3032
+ }
3033
+
3034
+ fn calc_pull_ratio(x: u64, ax: u64, ay: u64, bx: u64, by: u64) -> u64 {
3035
+ // must have neg slope, inversely proportional
3036
+ assert!(ax < bx);
3037
+ assert!(ay > by);
3038
+
3039
+ let neg_dy = ay - by;
3040
+ let dx = bx - ax;
3041
+ let neg_b = ay * neg_dy / dx;
3042
+
3043
+ return neg_b.saturating_sub(x * neg_dy / dx);
3044
+ }