@alchemy.run/effect-cluster 0.0.0 → 2.0.0-beta.86
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.
- package/LICENSE +201 -0
- package/README.md +101 -4
- package/lib/AWS/Database.d.ts +54 -0
- package/lib/AWS/Database.d.ts.map +1 -0
- package/lib/AWS/Database.js +96 -0
- package/lib/AWS/Database.js.map +1 -0
- package/lib/AWS/EcsPool.d.ts +56 -0
- package/lib/AWS/EcsPool.d.ts.map +1 -0
- package/lib/AWS/EcsPool.js +87 -0
- package/lib/AWS/EcsPool.js.map +1 -0
- package/lib/AWS/index.d.ts +7 -0
- package/lib/AWS/index.d.ts.map +1 -0
- package/lib/AWS/index.js +7 -0
- package/lib/AWS/index.js.map +1 -0
- package/lib/AWS/internal/Gateway.d.ts +23 -0
- package/lib/AWS/internal/Gateway.d.ts.map +1 -0
- package/lib/AWS/internal/Gateway.js +70 -0
- package/lib/AWS/internal/Gateway.js.map +1 -0
- package/lib/Cloudflare/DurableObjectPool.d.ts +42 -0
- package/lib/Cloudflare/DurableObjectPool.d.ts.map +1 -0
- package/lib/Cloudflare/DurableObjectPool.js +136 -0
- package/lib/Cloudflare/DurableObjectPool.js.map +1 -0
- package/lib/Cloudflare/PoolWorker.d.ts +186 -0
- package/lib/Cloudflare/PoolWorker.d.ts.map +1 -0
- package/lib/Cloudflare/PoolWorker.js +75 -0
- package/lib/Cloudflare/PoolWorker.js.map +1 -0
- package/lib/Cloudflare/index.d.ts +7 -0
- package/lib/Cloudflare/index.d.ts.map +1 -0
- package/lib/Cloudflare/index.js +7 -0
- package/lib/Cloudflare/index.js.map +1 -0
- package/lib/Cloudflare/internal/Objects.d.ts +38 -0
- package/lib/Cloudflare/internal/Objects.d.ts.map +1 -0
- package/lib/Cloudflare/internal/Objects.js +102 -0
- package/lib/Cloudflare/internal/Objects.js.map +1 -0
- package/lib/Cron.d.ts +143 -0
- package/lib/Cron.d.ts.map +1 -0
- package/lib/Cron.js +83 -0
- package/lib/Cron.js.map +1 -0
- package/lib/Database.d.ts +95 -0
- package/lib/Database.d.ts.map +1 -0
- package/lib/Database.js +38 -0
- package/lib/Database.js.map +1 -0
- package/lib/Docker/Database.d.ts +42 -0
- package/lib/Docker/Database.d.ts.map +1 -0
- package/lib/Docker/Database.js +53 -0
- package/lib/Docker/Database.js.map +1 -0
- package/lib/Docker/SwarmPool.d.ts +44 -0
- package/lib/Docker/SwarmPool.d.ts.map +1 -0
- package/lib/Docker/SwarmPool.js +56 -0
- package/lib/Docker/SwarmPool.js.map +1 -0
- package/lib/Docker/index.d.ts +7 -0
- package/lib/Docker/index.d.ts.map +1 -0
- package/lib/Docker/index.js +7 -0
- package/lib/Docker/index.js.map +1 -0
- package/lib/Entity.d.ts +348 -0
- package/lib/Entity.d.ts.map +1 -0
- package/lib/Entity.js +308 -0
- package/lib/Entity.js.map +1 -0
- package/lib/Fly/Database.d.ts +50 -0
- package/lib/Fly/Database.d.ts.map +1 -0
- package/lib/Fly/Database.js +56 -0
- package/lib/Fly/Database.js.map +1 -0
- package/lib/Fly/MachinePool.d.ts +39 -0
- package/lib/Fly/MachinePool.d.ts.map +1 -0
- package/lib/Fly/MachinePool.js +51 -0
- package/lib/Fly/MachinePool.js.map +1 -0
- package/lib/Fly/index.d.ts +7 -0
- package/lib/Fly/index.d.ts.map +1 -0
- package/lib/Fly/index.js +7 -0
- package/lib/Fly/index.js.map +1 -0
- package/lib/GCP/ComputeEnginePool.d.ts +41 -0
- package/lib/GCP/ComputeEnginePool.d.ts.map +1 -0
- package/lib/GCP/ComputeEnginePool.js +172 -0
- package/lib/GCP/ComputeEnginePool.js.map +1 -0
- package/lib/GCP/Database.d.ts +48 -0
- package/lib/GCP/Database.d.ts.map +1 -0
- package/lib/GCP/Database.js +115 -0
- package/lib/GCP/Database.js.map +1 -0
- package/lib/GCP/index.d.ts +7 -0
- package/lib/GCP/index.d.ts.map +1 -0
- package/lib/GCP/index.js +7 -0
- package/lib/GCP/index.js.map +1 -0
- package/lib/Hetzner/Database.d.ts +48 -0
- package/lib/Hetzner/Database.d.ts.map +1 -0
- package/lib/Hetzner/Database.js +91 -0
- package/lib/Hetzner/Database.js.map +1 -0
- package/lib/Hetzner/ServerPool.d.ts +35 -0
- package/lib/Hetzner/ServerPool.d.ts.map +1 -0
- package/lib/Hetzner/ServerPool.js +98 -0
- package/lib/Hetzner/ServerPool.js.map +1 -0
- package/lib/Hetzner/index.d.ts +7 -0
- package/lib/Hetzner/index.d.ts.map +1 -0
- package/lib/Hetzner/index.js +7 -0
- package/lib/Hetzner/index.js.map +1 -0
- package/lib/Host.d.ts +60 -0
- package/lib/Host.d.ts.map +1 -0
- package/lib/Host.js +31 -0
- package/lib/Host.js.map +1 -0
- package/lib/Kubernetes/Database.d.ts +40 -0
- package/lib/Kubernetes/Database.d.ts.map +1 -0
- package/lib/Kubernetes/Database.js +56 -0
- package/lib/Kubernetes/Database.js.map +1 -0
- package/lib/Kubernetes/DeploymentPool.d.ts +54 -0
- package/lib/Kubernetes/DeploymentPool.d.ts.map +1 -0
- package/lib/Kubernetes/DeploymentPool.js +49 -0
- package/lib/Kubernetes/DeploymentPool.js.map +1 -0
- package/lib/Kubernetes/index.d.ts +7 -0
- package/lib/Kubernetes/index.d.ts.map +1 -0
- package/lib/Kubernetes/index.js +7 -0
- package/lib/Kubernetes/index.js.map +1 -0
- package/lib/Pool.d.ts +66 -0
- package/lib/Pool.d.ts.map +1 -0
- package/lib/Pool.js +47 -0
- package/lib/Pool.js.map +1 -0
- package/lib/Providers.d.ts +19 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +31 -0
- package/lib/Providers.js.map +1 -0
- package/lib/ShardGroups.d.ts +24 -0
- package/lib/ShardGroups.d.ts.map +1 -0
- package/lib/ShardGroups.js +19 -0
- package/lib/ShardGroups.js.map +1 -0
- package/lib/Singleton.d.ts +110 -0
- package/lib/Singleton.d.ts.map +1 -0
- package/lib/Singleton.js +60 -0
- package/lib/Singleton.js.map +1 -0
- package/lib/Workflow.d.ts +251 -0
- package/lib/Workflow.d.ts.map +1 -0
- package/lib/Workflow.js +288 -0
- package/lib/Workflow.js.map +1 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/Bootstrap.d.ts +28 -0
- package/lib/internal/Bootstrap.d.ts.map +1 -0
- package/lib/internal/Bootstrap.js +257 -0
- package/lib/internal/Bootstrap.js.map +1 -0
- package/lib/internal/EntityRuntime.d.ts +40 -0
- package/lib/internal/EntityRuntime.d.ts.map +1 -0
- package/lib/internal/EntityRuntime.js +698 -0
- package/lib/internal/EntityRuntime.js.map +1 -0
- package/lib/internal/Gateway.d.ts +82 -0
- package/lib/internal/Gateway.d.ts.map +1 -0
- package/lib/internal/Gateway.js +218 -0
- package/lib/internal/Gateway.js.map +1 -0
- package/lib/internal/HostedPlatform.d.ts +36 -0
- package/lib/internal/HostedPlatform.d.ts.map +1 -0
- package/lib/internal/HostedPlatform.js +36 -0
- package/lib/internal/HostedPlatform.js.map +1 -0
- package/lib/internal/HostedRuntime.d.ts +58 -0
- package/lib/internal/HostedRuntime.d.ts.map +1 -0
- package/lib/internal/HostedRuntime.js +72 -0
- package/lib/internal/HostedRuntime.js.map +1 -0
- package/lib/internal/Naming.d.ts +12 -0
- package/lib/internal/Naming.d.ts.map +1 -0
- package/lib/internal/Naming.js +40 -0
- package/lib/internal/Naming.js.map +1 -0
- package/lib/internal/ObjectSharding.d.ts +141 -0
- package/lib/internal/ObjectSharding.d.ts.map +1 -0
- package/lib/internal/ObjectSharding.js +337 -0
- package/lib/internal/ObjectSharding.js.map +1 -0
- package/lib/internal/PoolHost.d.ts +80 -0
- package/lib/internal/PoolHost.d.ts.map +1 -0
- package/lib/internal/PoolHost.js +203 -0
- package/lib/internal/PoolHost.js.map +1 -0
- package/lib/internal/PoolHostService.d.ts +25 -0
- package/lib/internal/PoolHostService.d.ts.map +1 -0
- package/lib/internal/PoolHostService.js +10 -0
- package/lib/internal/PoolHostService.js.map +1 -0
- package/lib/internal/Wire.d.ts +60 -0
- package/lib/internal/Wire.d.ts.map +1 -0
- package/lib/internal/Wire.js +36 -0
- package/lib/internal/Wire.js.map +1 -0
- package/lib/internal/WorkflowGateway.d.ts +36 -0
- package/lib/internal/WorkflowGateway.d.ts.map +1 -0
- package/lib/internal/WorkflowGateway.js +124 -0
- package/lib/internal/WorkflowGateway.js.map +1 -0
- package/lib/internal/external-runner.d.ts +2 -0
- package/lib/internal/external-runner.d.ts.map +1 -0
- package/lib/internal/external-runner.js +7 -0
- package/lib/internal/external-runner.js.map +1 -0
- package/lib/internal/runner.d.ts +2 -0
- package/lib/internal/runner.d.ts.map +1 -0
- package/lib/internal/runner.js +5 -0
- package/lib/internal/runner.js.map +1 -0
- package/package.json +128 -3
- package/src/AWS/Database.ts +139 -0
- package/src/AWS/EcsPool.ts +118 -0
- package/src/AWS/index.ts +6 -0
- package/src/AWS/internal/Gateway.ts +82 -0
- package/src/Cloudflare/DurableObjectPool.ts +198 -0
- package/src/Cloudflare/PoolWorker.ts +124 -0
- package/src/Cloudflare/index.ts +6 -0
- package/src/Cloudflare/internal/Objects.ts +160 -0
- package/src/Cron.ts +202 -0
- package/src/Database.ts +116 -0
- package/src/Docker/Database.ts +94 -0
- package/src/Docker/SwarmPool.ts +83 -0
- package/src/Docker/index.ts +6 -0
- package/src/Entity.ts +621 -0
- package/src/Fly/Database.ts +102 -0
- package/src/Fly/MachinePool.ts +72 -0
- package/src/Fly/index.ts +6 -0
- package/src/GCP/ComputeEnginePool.ts +203 -0
- package/src/GCP/Database.ts +168 -0
- package/src/GCP/index.ts +6 -0
- package/src/Hetzner/Database.ts +142 -0
- package/src/Hetzner/ServerPool.ts +116 -0
- package/src/Hetzner/index.ts +6 -0
- package/src/Host.ts +68 -0
- package/src/Kubernetes/Database.ts +89 -0
- package/src/Kubernetes/DeploymentPool.ts +77 -0
- package/src/Kubernetes/index.ts +6 -0
- package/src/Pool.ts +104 -0
- package/src/Providers.ts +49 -0
- package/src/ShardGroups.ts +41 -0
- package/src/Singleton.ts +153 -0
- package/src/Workflow.ts +556 -0
- package/src/index.ts +11 -0
- package/src/internal/Bootstrap.ts +368 -0
- package/src/internal/EntityRuntime.ts +996 -0
- package/src/internal/Gateway.ts +366 -0
- package/src/internal/HostedPlatform.ts +83 -0
- package/src/internal/HostedRuntime.ts +118 -0
- package/src/internal/Naming.ts +44 -0
- package/src/internal/ObjectSharding.ts +578 -0
- package/src/internal/PoolHost.ts +330 -0
- package/src/internal/PoolHostService.ts +25 -0
- package/src/internal/Wire.ts +83 -0
- package/src/internal/WorkflowGateway.ts +188 -0
- package/src/internal/external-runner.ts +10 -0
- package/src/internal/runner.ts +5 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowGateway.js","sources":["../../src/internal/WorkflowGateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,iBAAiB,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAuB,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC7F,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAsB,YAAY,EAAE,MAAM,cAAc,CAAC;AAE9E,MAAM,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AAEpE,MAAM,OAAO,YAAa,SAAQ,QAAQ,CAAC,IAAI,CAC7C,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,EAC5E,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE;IACxB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;KACvC,CAAC;CACH,CAAC,EACF,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAChD,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAC/F;CAAG;AAEJ,MAAM,eAAgB,SAAQ,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAEtE;CAAG;AAEL,uFAAuF;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAA4C,EAAE,EAAE,CAC/E,YAAY,CAAC,OAAO,CAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC;IACpD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE;QAC5B,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,QAAQ,KAAK,SAAS;YAC3B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACrD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAoD,CAAC,CAAC;IAC3E,CAAC,CAAC;IACF,OAAO,YAAY,CAAC,EAAE,CAAC;QACrB,gBAAgB,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,CAC7D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CACrF,MAAM,CAAC,KAAK,CACb,CAAC;YACF,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE;gBAC9B,WAAW;gBACX,OAAO,EAAE,OAAiB;gBAC1B,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QACvB,eAAe,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CACnD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YACzD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,MAAe,EAAE,CAAC;YAC7D,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO,EAAE,KAAK,EAAE,WAAoB,EAAE,CAAC;YAC9E,OAAO;gBACL,KAAK,EAAE,UAAmB;gBAC1B,MAAM,EAAE,KAAK,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;aACzD,CAAC;QACJ,CAAC,CAAC;QACJ,oBAAoB,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CACxD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACnF,qEAAqE;QACrE,gEAAgE;QAChE,iBAAiB,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAC3D,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAC3C,MAAM,CAAC,YAAY,CACjB,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EAC9E,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAC3E,CACF;KACJ,CAAC,CAAC;AACL,CAAC,CAAC,CACH,CAAC;AAEJ,oEAAoE;AACpE,MAAM,UAAW,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAE5D;CAAG;AAEL,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AAEhF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAA6D,EACnB,EAAE;IAC5C,MAAM,IAAI,GAAG,CACX,YAAoB,EACpB,GAE8B,EAC9B,EAAE,CACF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,iBAAiB,CAAC;YAC3C,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,YAAY,EAAE;YACvD,eAAe,EAAE,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SACpF,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC5E,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAClE,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EACxB,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAClF,CAAC;IACJ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAExB,MAAM,IAAI,GAAG,CAAC,QAAsB,EAAE,WAAmB,EAAE,EAAE,CAC3D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAClD,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAClE,CAAC;QACF,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC,IAAI,EAAqC,CAAC;QACpF,IAAI,KAAK,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACjF,OAAO,MAAM,CAAC,IAAI,CAChB,KAAK,CAAC,CAAC,YAAY,CAAC,QAAiC,EAAE,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC,CAC/E,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,OAAO,cAAc,CAAC,UAAU,CAAC;QAC/B,0DAA0D;QAC1D,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;QAC3B,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAC7B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,QAAiC,CAAC,CAAC,CACzF,OAAO,CAAC,OAAO,CAChB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrB,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CACpC,MAAM,CAAC,gBAAgB,CAAC,CAAC;gBACvB,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,OAAO;aACR,CAAC,CACH,CAAC;YACF,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,SAAS,CAAC;YACtC,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,CACvE,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAC5B,CAAC;QACJ,CAAC,CAAuB;QAC1B,IAAI;QACJ,SAAS,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,CACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAC7B,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CACvE;QACH,eAAe,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,CACzC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAC7B,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CACvE;QACH,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;QACzB,eAAe,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC;QACnD,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,uBAAuB,CAAC;QACrD,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,CAClE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CACxC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAC5B,MAAM,CAAC,iBAAiB,CAAC,CAAC;YACxB,QAAQ,EAAE,YAAY;YACtB,WAAW;YACX,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,IAAI;SACX,CAAC,CACH,CACF;QACH,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC;KACvD,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sources":["../../src/internal/runner.ts"],"names":[],"mappings":""}
|
|
@@ -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.
|
|
3
|
+
"version": "2.0.0-beta.86",
|
|
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.86",
|
|
99
|
+
"@alchemy.run/cloudflare": "2.0.0-beta.86",
|
|
100
|
+
"@alchemy.run/docker": "2.0.0-beta.86",
|
|
101
|
+
"@alchemy.run/fly": "2.0.0-beta.86",
|
|
102
|
+
"@alchemy.run/gcp": "2.0.0-beta.86",
|
|
103
|
+
"@alchemy.run/hetzner": "2.0.0-beta.86",
|
|
104
|
+
"@alchemy.run/kubernetes": "2.0.0-beta.86",
|
|
105
|
+
"alchemy": "2.0.0-beta.86",
|
|
106
|
+
"effect": "^4.1.4"
|
|
107
|
+
},
|
|
108
|
+
"peerDependencies": {
|
|
109
|
+
"@alchemy.run/aws": "2.0.0-beta.86",
|
|
110
|
+
"@alchemy.run/cloudflare": "2.0.0-beta.86",
|
|
111
|
+
"@alchemy.run/docker": "2.0.0-beta.86",
|
|
112
|
+
"@alchemy.run/fly": "2.0.0-beta.86",
|
|
113
|
+
"@alchemy.run/gcp": "2.0.0-beta.86",
|
|
114
|
+
"@alchemy.run/hetzner": "2.0.0-beta.86",
|
|
115
|
+
"@alchemy.run/kubernetes": "2.0.0-beta.86",
|
|
116
|
+
"alchemy": "2.0.0-beta.86",
|
|
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
|
+
});
|
package/src/AWS/index.ts
ADDED
|
@@ -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
|
+
});
|