@alchemy.run/effect-cluster 0.0.0 → 2.0.0-beta.87

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 (233) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +101 -4
  3. package/lib/AWS/Database.d.ts +54 -0
  4. package/lib/AWS/Database.d.ts.map +1 -0
  5. package/lib/AWS/Database.js +96 -0
  6. package/lib/AWS/Database.js.map +1 -0
  7. package/lib/AWS/EcsPool.d.ts +56 -0
  8. package/lib/AWS/EcsPool.d.ts.map +1 -0
  9. package/lib/AWS/EcsPool.js +87 -0
  10. package/lib/AWS/EcsPool.js.map +1 -0
  11. package/lib/AWS/index.d.ts +7 -0
  12. package/lib/AWS/index.d.ts.map +1 -0
  13. package/lib/AWS/index.js +7 -0
  14. package/lib/AWS/index.js.map +1 -0
  15. package/lib/AWS/internal/Gateway.d.ts +23 -0
  16. package/lib/AWS/internal/Gateway.d.ts.map +1 -0
  17. package/lib/AWS/internal/Gateway.js +70 -0
  18. package/lib/AWS/internal/Gateway.js.map +1 -0
  19. package/lib/Cloudflare/DurableObjectPool.d.ts +42 -0
  20. package/lib/Cloudflare/DurableObjectPool.d.ts.map +1 -0
  21. package/lib/Cloudflare/DurableObjectPool.js +136 -0
  22. package/lib/Cloudflare/DurableObjectPool.js.map +1 -0
  23. package/lib/Cloudflare/PoolWorker.d.ts +186 -0
  24. package/lib/Cloudflare/PoolWorker.d.ts.map +1 -0
  25. package/lib/Cloudflare/PoolWorker.js +75 -0
  26. package/lib/Cloudflare/PoolWorker.js.map +1 -0
  27. package/lib/Cloudflare/index.d.ts +7 -0
  28. package/lib/Cloudflare/index.d.ts.map +1 -0
  29. package/lib/Cloudflare/index.js +7 -0
  30. package/lib/Cloudflare/index.js.map +1 -0
  31. package/lib/Cloudflare/internal/Objects.d.ts +38 -0
  32. package/lib/Cloudflare/internal/Objects.d.ts.map +1 -0
  33. package/lib/Cloudflare/internal/Objects.js +102 -0
  34. package/lib/Cloudflare/internal/Objects.js.map +1 -0
  35. package/lib/Cron.d.ts +143 -0
  36. package/lib/Cron.d.ts.map +1 -0
  37. package/lib/Cron.js +83 -0
  38. package/lib/Cron.js.map +1 -0
  39. package/lib/Database.d.ts +95 -0
  40. package/lib/Database.d.ts.map +1 -0
  41. package/lib/Database.js +38 -0
  42. package/lib/Database.js.map +1 -0
  43. package/lib/Docker/Database.d.ts +42 -0
  44. package/lib/Docker/Database.d.ts.map +1 -0
  45. package/lib/Docker/Database.js +53 -0
  46. package/lib/Docker/Database.js.map +1 -0
  47. package/lib/Docker/SwarmPool.d.ts +44 -0
  48. package/lib/Docker/SwarmPool.d.ts.map +1 -0
  49. package/lib/Docker/SwarmPool.js +56 -0
  50. package/lib/Docker/SwarmPool.js.map +1 -0
  51. package/lib/Docker/index.d.ts +7 -0
  52. package/lib/Docker/index.d.ts.map +1 -0
  53. package/lib/Docker/index.js +7 -0
  54. package/lib/Docker/index.js.map +1 -0
  55. package/lib/Entity.d.ts +348 -0
  56. package/lib/Entity.d.ts.map +1 -0
  57. package/lib/Entity.js +308 -0
  58. package/lib/Entity.js.map +1 -0
  59. package/lib/Fly/Database.d.ts +50 -0
  60. package/lib/Fly/Database.d.ts.map +1 -0
  61. package/lib/Fly/Database.js +56 -0
  62. package/lib/Fly/Database.js.map +1 -0
  63. package/lib/Fly/MachinePool.d.ts +39 -0
  64. package/lib/Fly/MachinePool.d.ts.map +1 -0
  65. package/lib/Fly/MachinePool.js +51 -0
  66. package/lib/Fly/MachinePool.js.map +1 -0
  67. package/lib/Fly/index.d.ts +7 -0
  68. package/lib/Fly/index.d.ts.map +1 -0
  69. package/lib/Fly/index.js +7 -0
  70. package/lib/Fly/index.js.map +1 -0
  71. package/lib/GCP/ComputeEnginePool.d.ts +41 -0
  72. package/lib/GCP/ComputeEnginePool.d.ts.map +1 -0
  73. package/lib/GCP/ComputeEnginePool.js +172 -0
  74. package/lib/GCP/ComputeEnginePool.js.map +1 -0
  75. package/lib/GCP/Database.d.ts +48 -0
  76. package/lib/GCP/Database.d.ts.map +1 -0
  77. package/lib/GCP/Database.js +115 -0
  78. package/lib/GCP/Database.js.map +1 -0
  79. package/lib/GCP/index.d.ts +7 -0
  80. package/lib/GCP/index.d.ts.map +1 -0
  81. package/lib/GCP/index.js +7 -0
  82. package/lib/GCP/index.js.map +1 -0
  83. package/lib/Hetzner/Database.d.ts +48 -0
  84. package/lib/Hetzner/Database.d.ts.map +1 -0
  85. package/lib/Hetzner/Database.js +91 -0
  86. package/lib/Hetzner/Database.js.map +1 -0
  87. package/lib/Hetzner/ServerPool.d.ts +35 -0
  88. package/lib/Hetzner/ServerPool.d.ts.map +1 -0
  89. package/lib/Hetzner/ServerPool.js +98 -0
  90. package/lib/Hetzner/ServerPool.js.map +1 -0
  91. package/lib/Hetzner/index.d.ts +7 -0
  92. package/lib/Hetzner/index.d.ts.map +1 -0
  93. package/lib/Hetzner/index.js +7 -0
  94. package/lib/Hetzner/index.js.map +1 -0
  95. package/lib/Host.d.ts +60 -0
  96. package/lib/Host.d.ts.map +1 -0
  97. package/lib/Host.js +31 -0
  98. package/lib/Host.js.map +1 -0
  99. package/lib/Kubernetes/Database.d.ts +40 -0
  100. package/lib/Kubernetes/Database.d.ts.map +1 -0
  101. package/lib/Kubernetes/Database.js +56 -0
  102. package/lib/Kubernetes/Database.js.map +1 -0
  103. package/lib/Kubernetes/DeploymentPool.d.ts +54 -0
  104. package/lib/Kubernetes/DeploymentPool.d.ts.map +1 -0
  105. package/lib/Kubernetes/DeploymentPool.js +49 -0
  106. package/lib/Kubernetes/DeploymentPool.js.map +1 -0
  107. package/lib/Kubernetes/index.d.ts +7 -0
  108. package/lib/Kubernetes/index.d.ts.map +1 -0
  109. package/lib/Kubernetes/index.js +7 -0
  110. package/lib/Kubernetes/index.js.map +1 -0
  111. package/lib/Pool.d.ts +66 -0
  112. package/lib/Pool.d.ts.map +1 -0
  113. package/lib/Pool.js +47 -0
  114. package/lib/Pool.js.map +1 -0
  115. package/lib/Providers.d.ts +19 -0
  116. package/lib/Providers.d.ts.map +1 -0
  117. package/lib/Providers.js +31 -0
  118. package/lib/Providers.js.map +1 -0
  119. package/lib/ShardGroups.d.ts +24 -0
  120. package/lib/ShardGroups.d.ts.map +1 -0
  121. package/lib/ShardGroups.js +19 -0
  122. package/lib/ShardGroups.js.map +1 -0
  123. package/lib/Singleton.d.ts +110 -0
  124. package/lib/Singleton.d.ts.map +1 -0
  125. package/lib/Singleton.js +60 -0
  126. package/lib/Singleton.js.map +1 -0
  127. package/lib/Workflow.d.ts +251 -0
  128. package/lib/Workflow.d.ts.map +1 -0
  129. package/lib/Workflow.js +288 -0
  130. package/lib/Workflow.js.map +1 -0
  131. package/lib/index.d.ts +12 -0
  132. package/lib/index.d.ts.map +1 -0
  133. package/lib/index.js +12 -0
  134. package/lib/index.js.map +1 -0
  135. package/lib/internal/Bootstrap.d.ts +28 -0
  136. package/lib/internal/Bootstrap.d.ts.map +1 -0
  137. package/lib/internal/Bootstrap.js +257 -0
  138. package/lib/internal/Bootstrap.js.map +1 -0
  139. package/lib/internal/EntityRuntime.d.ts +40 -0
  140. package/lib/internal/EntityRuntime.d.ts.map +1 -0
  141. package/lib/internal/EntityRuntime.js +698 -0
  142. package/lib/internal/EntityRuntime.js.map +1 -0
  143. package/lib/internal/Gateway.d.ts +82 -0
  144. package/lib/internal/Gateway.d.ts.map +1 -0
  145. package/lib/internal/Gateway.js +219 -0
  146. package/lib/internal/Gateway.js.map +1 -0
  147. package/lib/internal/HostedPlatform.d.ts +36 -0
  148. package/lib/internal/HostedPlatform.d.ts.map +1 -0
  149. package/lib/internal/HostedPlatform.js +36 -0
  150. package/lib/internal/HostedPlatform.js.map +1 -0
  151. package/lib/internal/HostedRuntime.d.ts +58 -0
  152. package/lib/internal/HostedRuntime.d.ts.map +1 -0
  153. package/lib/internal/HostedRuntime.js +72 -0
  154. package/lib/internal/HostedRuntime.js.map +1 -0
  155. package/lib/internal/Naming.d.ts +12 -0
  156. package/lib/internal/Naming.d.ts.map +1 -0
  157. package/lib/internal/Naming.js +40 -0
  158. package/lib/internal/Naming.js.map +1 -0
  159. package/lib/internal/ObjectSharding.d.ts +141 -0
  160. package/lib/internal/ObjectSharding.d.ts.map +1 -0
  161. package/lib/internal/ObjectSharding.js +337 -0
  162. package/lib/internal/ObjectSharding.js.map +1 -0
  163. package/lib/internal/PoolHost.d.ts +80 -0
  164. package/lib/internal/PoolHost.d.ts.map +1 -0
  165. package/lib/internal/PoolHost.js +203 -0
  166. package/lib/internal/PoolHost.js.map +1 -0
  167. package/lib/internal/PoolHostService.d.ts +25 -0
  168. package/lib/internal/PoolHostService.d.ts.map +1 -0
  169. package/lib/internal/PoolHostService.js +10 -0
  170. package/lib/internal/PoolHostService.js.map +1 -0
  171. package/lib/internal/Wire.d.ts +60 -0
  172. package/lib/internal/Wire.d.ts.map +1 -0
  173. package/lib/internal/Wire.js +36 -0
  174. package/lib/internal/Wire.js.map +1 -0
  175. package/lib/internal/WorkflowGateway.d.ts +36 -0
  176. package/lib/internal/WorkflowGateway.d.ts.map +1 -0
  177. package/lib/internal/WorkflowGateway.js +124 -0
  178. package/lib/internal/WorkflowGateway.js.map +1 -0
  179. package/lib/internal/external-runner.d.ts +2 -0
  180. package/lib/internal/external-runner.d.ts.map +1 -0
  181. package/lib/internal/external-runner.js +7 -0
  182. package/lib/internal/external-runner.js.map +1 -0
  183. package/lib/internal/runner.d.ts +2 -0
  184. package/lib/internal/runner.d.ts.map +1 -0
  185. package/lib/internal/runner.js +5 -0
  186. package/lib/internal/runner.js.map +1 -0
  187. package/package.json +128 -3
  188. package/src/AWS/Database.ts +139 -0
  189. package/src/AWS/EcsPool.ts +118 -0
  190. package/src/AWS/index.ts +6 -0
  191. package/src/AWS/internal/Gateway.ts +82 -0
  192. package/src/Cloudflare/DurableObjectPool.ts +198 -0
  193. package/src/Cloudflare/PoolWorker.ts +124 -0
  194. package/src/Cloudflare/index.ts +6 -0
  195. package/src/Cloudflare/internal/Objects.ts +160 -0
  196. package/src/Cron.ts +202 -0
  197. package/src/Database.ts +116 -0
  198. package/src/Docker/Database.ts +94 -0
  199. package/src/Docker/SwarmPool.ts +83 -0
  200. package/src/Docker/index.ts +6 -0
  201. package/src/Entity.ts +621 -0
  202. package/src/Fly/Database.ts +102 -0
  203. package/src/Fly/MachinePool.ts +72 -0
  204. package/src/Fly/index.ts +6 -0
  205. package/src/GCP/ComputeEnginePool.ts +203 -0
  206. package/src/GCP/Database.ts +168 -0
  207. package/src/GCP/index.ts +6 -0
  208. package/src/Hetzner/Database.ts +142 -0
  209. package/src/Hetzner/ServerPool.ts +116 -0
  210. package/src/Hetzner/index.ts +6 -0
  211. package/src/Host.ts +68 -0
  212. package/src/Kubernetes/Database.ts +89 -0
  213. package/src/Kubernetes/DeploymentPool.ts +77 -0
  214. package/src/Kubernetes/index.ts +6 -0
  215. package/src/Pool.ts +104 -0
  216. package/src/Providers.ts +49 -0
  217. package/src/ShardGroups.ts +41 -0
  218. package/src/Singleton.ts +153 -0
  219. package/src/Workflow.ts +556 -0
  220. package/src/index.ts +11 -0
  221. package/src/internal/Bootstrap.ts +368 -0
  222. package/src/internal/EntityRuntime.ts +996 -0
  223. package/src/internal/Gateway.ts +367 -0
  224. package/src/internal/HostedPlatform.ts +83 -0
  225. package/src/internal/HostedRuntime.ts +118 -0
  226. package/src/internal/Naming.ts +44 -0
  227. package/src/internal/ObjectSharding.ts +578 -0
  228. package/src/internal/PoolHost.ts +330 -0
  229. package/src/internal/PoolHostService.ts +25 -0
  230. package/src/internal/Wire.ts +83 -0
  231. package/src/internal/WorkflowGateway.ts +188 -0
  232. package/src/internal/external-runner.ts +10 -0
  233. package/src/internal/runner.ts +5 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowGateway.js","sources":["../../src/internal/WorkflowGateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=external-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-runner.d.ts","sources":["../../src/internal/external-runner.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ // @ts-expect-error resolved by the pool's bundler plugin
2
+ import entities from "virtual:cluster-entities";
3
+ // @ts-expect-error resolved by the pool's bundler plugin
4
+ import program from "virtual:cluster-program";
5
+ import { runExternal } from "./Bootstrap.js";
6
+ await runExternal(entities, program);
7
+ //# sourceMappingURL=external-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-runner.js","sources":["../../src/internal/external-runner.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAChD,yDAAyD;AACzD,OAAO,OAAO,MAAM,yBAAyB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,CACf,QAA6E,EAC7E,OAAiB,CAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sources":["../../src/internal/runner.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ // @ts-expect-error resolved by the pool's bundler plugin
2
+ import entities from "virtual:cluster-entities";
3
+ import { bootstrap } from "./Bootstrap.js";
4
+ await bootstrap(entities);
5
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sources":["../../src/internal/runner.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,SAAS,CAAC,QAA6E,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy.run/effect-cluster",
3
- "version": "0.0.0",
3
+ "version": "2.0.0-beta.87",
4
4
  "description": "Effect Cluster entities, with their database and runners on any cloud, for Alchemy.",
5
5
  "keywords": [
6
6
  "alchemy",
@@ -10,12 +10,137 @@
10
10
  "infrastructure-as-code",
11
11
  "sharding"
12
12
  ],
13
+ "homepage": "https://alchemy.run",
14
+ "bugs": {
15
+ "url": "https://github.com/alchemy-run/alchemy/issues"
16
+ },
13
17
  "license": "Apache-2.0",
14
18
  "author": "Sam Goodwin <sam@alchemy.run>",
15
- "homepage": "https://alchemy.run",
16
19
  "repository": {
17
20
  "type": "git",
18
21
  "url": "git+https://github.com/alchemy-run/alchemy.git",
19
22
  "directory": "packages/effect-cluster"
23
+ },
24
+ "files": [
25
+ "lib",
26
+ "src"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "exports": {
31
+ ".": {
32
+ "types": "./lib/index.d.ts",
33
+ "bun": "./src/index.ts",
34
+ "worker": "./src/index.ts",
35
+ "default": "./lib/index.js"
36
+ },
37
+ "./AWS": {
38
+ "types": "./lib/AWS/index.d.ts",
39
+ "bun": "./src/AWS/index.ts",
40
+ "worker": "./src/AWS/index.ts",
41
+ "default": "./lib/AWS/index.js"
42
+ },
43
+ "./Cloudflare": {
44
+ "types": "./lib/Cloudflare/index.d.ts",
45
+ "bun": "./src/Cloudflare/index.ts",
46
+ "worker": "./src/Cloudflare/index.ts",
47
+ "default": "./lib/Cloudflare/index.js"
48
+ },
49
+ "./Docker": {
50
+ "types": "./lib/Docker/index.d.ts",
51
+ "bun": "./src/Docker/index.ts",
52
+ "worker": "./src/Docker/index.ts",
53
+ "default": "./lib/Docker/index.js"
54
+ },
55
+ "./Fly": {
56
+ "types": "./lib/Fly/index.d.ts",
57
+ "bun": "./src/Fly/index.ts",
58
+ "worker": "./src/Fly/index.ts",
59
+ "default": "./lib/Fly/index.js"
60
+ },
61
+ "./GCP": {
62
+ "types": "./lib/GCP/index.d.ts",
63
+ "bun": "./src/GCP/index.ts",
64
+ "worker": "./src/GCP/index.ts",
65
+ "default": "./lib/GCP/index.js"
66
+ },
67
+ "./Hetzner": {
68
+ "types": "./lib/Hetzner/index.d.ts",
69
+ "bun": "./src/Hetzner/index.ts",
70
+ "worker": "./src/Hetzner/index.ts",
71
+ "default": "./lib/Hetzner/index.js"
72
+ },
73
+ "./Kubernetes": {
74
+ "types": "./lib/Kubernetes/index.d.ts",
75
+ "bun": "./src/Kubernetes/index.ts",
76
+ "worker": "./src/Kubernetes/index.ts",
77
+ "default": "./lib/Kubernetes/index.js"
78
+ },
79
+ "./AWS/internal/*": null,
80
+ "./Cloudflare/internal/*": null,
81
+ "./internal/*": null,
82
+ "./*": {
83
+ "types": "./lib/*.d.ts",
84
+ "bun": "./src/*.ts",
85
+ "worker": "./src/*.ts",
86
+ "default": "./lib/*.js"
87
+ },
88
+ "./package.json": "./package.json"
89
+ },
90
+ "publishConfig": {
91
+ "access": "public"
92
+ },
93
+ "dependencies": {
94
+ "@effect/platform-node": "^4.1.4",
95
+ "@effect/sql-pg": "^4.1.4"
96
+ },
97
+ "devDependencies": {
98
+ "@alchemy.run/aws": "2.0.0-beta.87",
99
+ "@alchemy.run/cloudflare": "2.0.0-beta.87",
100
+ "@alchemy.run/docker": "2.0.0-beta.87",
101
+ "@alchemy.run/fly": "2.0.0-beta.87",
102
+ "@alchemy.run/gcp": "2.0.0-beta.87",
103
+ "@alchemy.run/hetzner": "2.0.0-beta.87",
104
+ "@alchemy.run/kubernetes": "2.0.0-beta.87",
105
+ "alchemy": "2.0.0-beta.87",
106
+ "effect": "^4.1.4"
107
+ },
108
+ "peerDependencies": {
109
+ "@alchemy.run/aws": "2.0.0-beta.87",
110
+ "@alchemy.run/cloudflare": "2.0.0-beta.87",
111
+ "@alchemy.run/docker": "2.0.0-beta.87",
112
+ "@alchemy.run/fly": "2.0.0-beta.87",
113
+ "@alchemy.run/gcp": "2.0.0-beta.87",
114
+ "@alchemy.run/hetzner": "2.0.0-beta.87",
115
+ "@alchemy.run/kubernetes": "2.0.0-beta.87",
116
+ "alchemy": "2.0.0-beta.87",
117
+ "effect": "^4.1.4"
118
+ },
119
+ "peerDependenciesMeta": {
120
+ "@alchemy.run/aws": {
121
+ "optional": true
122
+ },
123
+ "@alchemy.run/cloudflare": {
124
+ "optional": true
125
+ },
126
+ "@alchemy.run/docker": {
127
+ "optional": true
128
+ },
129
+ "@alchemy.run/fly": {
130
+ "optional": true
131
+ },
132
+ "@alchemy.run/gcp": {
133
+ "optional": true
134
+ },
135
+ "@alchemy.run/hetzner": {
136
+ "optional": true
137
+ },
138
+ "@alchemy.run/kubernetes": {
139
+ "optional": true
140
+ }
141
+ },
142
+ "scripts": {
143
+ "build": "pnpm -r --filter \"{.}...\" run build:package",
144
+ "build:package": "node scripts/build.ts"
20
145
  }
21
- }
146
+ }
@@ -0,0 +1,139 @@
1
+ import * as EC2 from "@alchemy.run/aws/EC2";
2
+ import * as RDS from "@alchemy.run/aws/RDS";
3
+ import * as Output from "alchemy/Output";
4
+ import { Random } from "alchemy/Random";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ import * as Redacted from "effect/Redacted";
8
+ import { clusterShardGroups, Database as ClusterDatabase } from "../Database.ts";
9
+ import { RUNNER_PORT } from "../internal/Gateway.ts";
10
+ import type { Providers } from "../Providers.ts";
11
+
12
+ export interface DatabaseProps {
13
+ /**
14
+ * RDS instance class.
15
+ * @default "db.t4g.micro"
16
+ */
17
+ instanceClass?: string;
18
+ /**
19
+ * Postgres major version.
20
+ * @default "17"
21
+ */
22
+ engineVersion?: string;
23
+ /**
24
+ * Storage, in GiB.
25
+ * @default 20
26
+ */
27
+ allocatedStorage?: number;
28
+ /**
29
+ * Run a standby in a second Availability Zone.
30
+ * @default false
31
+ */
32
+ multiAZ?: boolean;
33
+ /**
34
+ * IPv4 CIDR block of the cluster's VPC.
35
+ * @default "10.44.0.0/16"
36
+ */
37
+ cidrBlock?: string;
38
+ }
39
+
40
+ /**
41
+ * The database an Effect Cluster coordinates through, on AWS, as a
42
+ * `Cluster.Database` Layer: Postgres on RDS, in a VPC of its own that the
43
+ * runners join. Every runner joins one security group, which reaches the
44
+ * database and the other runners on the runner port; nothing else does.
45
+ *
46
+ * ### Running the database on RDS
47
+ * **Example:** Postgres for the cluster
48
+ * ```typescript
49
+ * export const Database = ClusterAWS.Database("Cluster");
50
+ * ```
51
+ *
52
+ * **Example:** A larger instance with a standby
53
+ * ```typescript
54
+ * export const Database = ClusterAWS.Database("Cluster", {
55
+ * instanceClass: "db.m7g.large",
56
+ * multiAZ: true,
57
+ * });
58
+ * ```
59
+ *
60
+ * @primitive
61
+ */
62
+ export const Database = (id: string, props: DatabaseProps = {}) =>
63
+ Layer.effect(
64
+ ClusterDatabase,
65
+ Effect.gen(function* () {
66
+ if (globalThis.__ALCHEMY_RUNTIME__) {
67
+ // Runners read their database from their own environment at runtime.
68
+ return { url: Redacted.make(""), shardGroups: undefined as never };
69
+ }
70
+ const network = yield* EC2.Network(`${id}Network`, {
71
+ cidrBlock: props.cidrBlock ?? "10.44.0.0/16",
72
+ availabilityZones: 2,
73
+ });
74
+ const runners = yield* EC2.SecurityGroup(`${id}RunnersGroup`, {
75
+ vpcId: network.vpcId,
76
+ description: "Effect Cluster runners",
77
+ egress: [{ ipProtocol: "-1", cidrIpv4: "0.0.0.0/0" }],
78
+ });
79
+ // Runners send each other messages for the shards they own.
80
+ yield* EC2.SecurityGroupRule(`${id}RunnerPeers`, {
81
+ groupId: runners.groupId,
82
+ type: "ingress",
83
+ ipProtocol: "tcp",
84
+ fromPort: RUNNER_PORT,
85
+ toPort: RUNNER_PORT,
86
+ referencedGroupId: runners.groupId,
87
+ });
88
+ const databaseGroup = yield* EC2.SecurityGroup(`${id}DatabaseGroup`, {
89
+ vpcId: network.vpcId,
90
+ description: "Effect Cluster database",
91
+ ingress: [
92
+ { ipProtocol: "tcp", fromPort: 5432, toPort: 5432, referencedGroupId: runners.groupId },
93
+ ],
94
+ egress: [{ ipProtocol: "-1", cidrIpv4: "0.0.0.0/0" }],
95
+ });
96
+ const subnets = yield* RDS.DBSubnetGroup(`${id}Subnets`, {
97
+ description: "Effect Cluster database",
98
+ subnetIds: network.publicSubnetIds,
99
+ });
100
+ const password = yield* Random(`${id}Password`, { bytes: 24 }) as unknown as Effect.Effect<
101
+ Random,
102
+ never,
103
+ Providers
104
+ >;
105
+ const instance = yield* RDS.DBInstance(`${id}Postgres`, {
106
+ engine: "postgres",
107
+ engineVersion: props.engineVersion ?? "17",
108
+ dbInstanceClass: props.instanceClass ?? "db.t4g.micro",
109
+ allocatedStorage: props.allocatedStorage ?? 20,
110
+ dbName: "effect_cluster",
111
+ masterUsername: "effect",
112
+ masterUserPassword: password.text,
113
+ multiAZ: props.multiAZ ?? false,
114
+ dbSubnetGroupName: subnets.dbSubnetGroupName,
115
+ vpcSecurityGroupIds: [databaseGroup.groupId],
116
+ publiclyAccessible: false,
117
+ storageEncrypted: true,
118
+ skipFinalSnapshot: true,
119
+ });
120
+ return {
121
+ // RDS requires TLS. Runners verify the certificate against the RDS
122
+ // certificate authority their image trusts (`ClusterAWS.EcsPool`).
123
+ url: Output.all(instance.endpointAddress, instance.endpointPort, password.text).pipe(
124
+ Output.map(([host, port, text]) =>
125
+ Redacted.make(
126
+ `postgres://effect:${encodeURIComponent(text.pipe(Redacted.value))}@${host}:${port ?? 5432}/effect_cluster?sslmode=require`,
127
+ ),
128
+ ),
129
+ ),
130
+ network: {
131
+ kind: "aws" as const,
132
+ vpcId: network.vpcId,
133
+ subnetIds: network.publicSubnetIds,
134
+ securityGroupId: runners.groupId,
135
+ },
136
+ shardGroups: yield* clusterShardGroups(id),
137
+ };
138
+ }),
139
+ );
@@ -0,0 +1,118 @@
1
+ import * as ECS from "@alchemy.run/aws/ECS";
2
+ import * as Output from "alchemy/Output";
3
+ import * as Effect from "effect/Effect";
4
+ import { GATEWAY_PORT, RUNNER_PORT } from "../internal/Gateway.ts";
5
+ import { makePoolLayer, RUNNER_DOCKERFILE, type PoolSettings } from "../internal/PoolHost.ts";
6
+
7
+ /** Where AWS publishes the certificate authorities of every RDS region. */
8
+ const RDS_CA_BUNDLE = "https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem";
9
+
10
+ const RDS_RUNNER_DOCKERFILE = RUNNER_DOCKERFILE.replace(
11
+ "ENV NODE_ENV=production",
12
+ `ENV NODE_ENV=production
13
+ ADD ${RDS_CA_BUNDLE} /etc/ssl/rds-ca.pem
14
+ ENV NODE_EXTRA_CA_CERTS=/etc/ssl/rds-ca.pem`,
15
+ );
16
+ import { awsNetworkOf, makeAwsGateway } from "./internal/Gateway.ts";
17
+
18
+ export interface EcsPoolOptions extends PoolSettings {
19
+ /**
20
+ * Number of runners.
21
+ * @default 2
22
+ */
23
+ replicas?: number;
24
+ /**
25
+ * CPU units of each runner (1024 = 1 vCPU).
26
+ * @default 512
27
+ */
28
+ cpu?: number;
29
+ /**
30
+ * Memory of each runner, in MiB.
31
+ * @default 1024
32
+ */
33
+ memory?: number;
34
+ /**
35
+ * CPU architecture of the pool. The image is built for it on the
36
+ * deploying machine.
37
+ * @default "X86_64"
38
+ */
39
+ architecture?: "X86_64" | "ARM64";
40
+ }
41
+
42
+ /**
43
+ * Run a pool of Effect Cluster runners on ECS Fargate: an ECS service whose tasks
44
+ * host every class given this pool, in the database's VPC, behind a
45
+ * load balancer that serves their gateway to callers anywhere. Requires a
46
+ * database in an AWS VPC — `ClusterAWS.Database`.
47
+ *
48
+ * Runners reach each other and the database through the cluster's runner
49
+ * security group; the load balancer only reaches the gateway, which checks
50
+ * every call's token.
51
+ *
52
+ * ### Running on ECS
53
+ * **Example:** Two runners on Fargate
54
+ * ```typescript
55
+ * export const Database = ClusterAWS.Database("Cluster");
56
+ * export const Default = ClusterAWS.EcsPool("Default", { replicas: 2 }).pipe(
57
+ * Layer.provide(Database),
58
+ * );
59
+ * ```
60
+ *
61
+ * **Example:** Larger Graviton runners
62
+ * ```typescript
63
+ * export const Default = ClusterAWS.EcsPool("Default", {
64
+ * cpu: 2048,
65
+ * memory: 4096,
66
+ * architecture: "ARM64",
67
+ * }).pipe(Layer.provide(Database));
68
+ * ```
69
+ *
70
+ * @primitive
71
+ */
72
+ export const EcsPool = (id: string, options: EcsPoolOptions = {}) =>
73
+ makePoolLayer({
74
+ label: "ClusterAWS.EcsPool",
75
+ id,
76
+ settings: options,
77
+ expected: "an AWS VPC (ClusterAWS.Database)",
78
+ // The runner image trusts the RDS certificate authority, so runners
79
+ // verify the database's certificate.
80
+ dockerfile: RDS_RUNNER_DOCKERFILE,
81
+ network: awsNetworkOf,
82
+ gateway: (_name, network) => makeAwsGateway(id, network, "ip"),
83
+ nodes: ({ network, gateway, program, environment }) =>
84
+ Effect.gen(function* () {
85
+ const cluster = yield* ECS.Cluster(`${id}Cluster`, {});
86
+ yield* ECS.Service(`${id}Pool`, {
87
+ cluster,
88
+ context: program.pipe(Output.map((p) => p.dir)) as unknown as string,
89
+ // Other runners reach the runner port; the load balancer, the gateway.
90
+ container: {
91
+ name: "runner",
92
+ portMappings: [
93
+ { containerPort: RUNNER_PORT, hostPort: RUNNER_PORT, protocol: "tcp" },
94
+ { containerPort: GATEWAY_PORT, hostPort: GATEWAY_PORT, protocol: "tcp" },
95
+ ],
96
+ },
97
+ desiredCount: options.replicas ?? 2,
98
+ cpu: options.cpu ?? 512,
99
+ memory: options.memory ?? 1024,
100
+ runtimePlatform: {
101
+ cpuArchitecture: options.architecture ?? "X86_64",
102
+ operatingSystemFamily: "LINUX",
103
+ },
104
+ vpcId: network.vpcId,
105
+ subnets: [...network.subnetIds],
106
+ securityGroups: [network.securityGroupId, gateway.securityGroupId],
107
+ assignPublicIp: true,
108
+ loadBalancers: [
109
+ {
110
+ targetGroupArn: gateway.targetGroupArn as unknown as string,
111
+ containerName: "runner",
112
+ containerPort: GATEWAY_PORT,
113
+ },
114
+ ],
115
+ env: environment as unknown as Record<string, string>,
116
+ });
117
+ }),
118
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @alchemy.run/effect-cluster/AWS — run an Effect Cluster's database and runners
3
+ * on AWS. Requires `@alchemy.run/aws`.
4
+ */
5
+ export * from "./Database.ts";
6
+ export * from "./EcsPool.ts";
@@ -0,0 +1,82 @@
1
+ /**
2
+ * What the AWS runners share: the database's VPC, and a load balancer that
3
+ * serves each pool's gateway to callers anywhere.
4
+ *
5
+ * @internal
6
+ */
7
+ import * as EC2 from "@alchemy.run/aws/EC2";
8
+ import * as ELBv2 from "@alchemy.run/aws/ELBv2";
9
+ import type { Input } from "alchemy/Input";
10
+ import * as Output from "alchemy/Output";
11
+ import * as Effect from "effect/Effect";
12
+ import type { ClusterNetwork, DatabaseShape } from "../../Database.ts";
13
+ import { GATEWAY_PORT } from "../../internal/Gateway.ts";
14
+
15
+ export type AwsNetwork = Extract<ClusterNetwork, { kind: "aws" }>;
16
+
17
+ export const awsNetworkOf = (database: DatabaseShape): AwsNetwork | undefined =>
18
+ database.network?.kind === "aws" ? database.network : undefined;
19
+
20
+ /**
21
+ * An internet-facing load balancer in front of the pool's gateway. It is
22
+ * declared before the pool, so the gateway's URL never depends on it.
23
+ */
24
+ export const makeAwsGateway = Effect.fn(function* (
25
+ id: string,
26
+ network: AwsNetwork,
27
+ targetType: "ip" | "instance",
28
+ ) {
29
+ // The database's network, as the EC2 identifiers it holds.
30
+ const vpcId = network.vpcId as Input<EC2.VpcId>;
31
+ const subnetIds = network.subnetIds as Input<EC2.SubnetId>[];
32
+ const balancerGroup = yield* EC2.SecurityGroup(`${id}GatewayBalancerGroup`, {
33
+ vpcId,
34
+ description: "Effect Cluster gateway load balancer",
35
+ ingress: [{ ipProtocol: "tcp", fromPort: 80, toPort: 80, cidrIpv4: "0.0.0.0/0" }],
36
+ egress: [{ ipProtocol: "-1", cidrIpv4: "0.0.0.0/0" }],
37
+ });
38
+ // Runners take gateway traffic only from their load balancer.
39
+ const gatewayGroup = yield* EC2.SecurityGroup(`${id}GatewayGroup`, {
40
+ vpcId,
41
+ description: "Effect Cluster gateway",
42
+ ingress: [
43
+ {
44
+ ipProtocol: "tcp",
45
+ fromPort: GATEWAY_PORT,
46
+ toPort: GATEWAY_PORT,
47
+ referencedGroupId: balancerGroup.groupId,
48
+ },
49
+ ],
50
+ egress: [{ ipProtocol: "-1", cidrIpv4: "0.0.0.0/0" }],
51
+ });
52
+ const targets = yield* ELBv2.TargetGroup(`${id}Gateway`, {
53
+ vpcId,
54
+ port: GATEWAY_PORT,
55
+ protocol: "HTTP",
56
+ targetType,
57
+ healthCheckPath: "/health",
58
+ matcher: { HttpCode: "200" },
59
+ });
60
+ const balancer = yield* ELBv2.LoadBalancer(`${id}GatewayBalancer`, {
61
+ type: "application",
62
+ scheme: "internet-facing",
63
+ subnets: subnetIds,
64
+ securityGroups: [balancerGroup.groupId],
65
+ // Streaming calls stay open.
66
+ attributes: { "idle_timeout.timeout_seconds": "3600" },
67
+ });
68
+ const listener = yield* ELBv2.Listener(`${id}GatewayListener`, {
69
+ loadBalancerArn: balancer.loadBalancerArn,
70
+ port: 80,
71
+ protocol: "HTTP",
72
+ targetGroupArn: targets.targetGroupArn,
73
+ });
74
+ return {
75
+ // Ordered after the listener, so callers use it once it serves.
76
+ url: Output.all(balancer.dnsName, listener.listenerArn).pipe(
77
+ Output.map(([dns]) => `http://${dns}`),
78
+ ),
79
+ targetGroupArn: targets.targetGroupArn,
80
+ securityGroupId: gatewayGroup.groupId,
81
+ };
82
+ });