AWS
Host your cluster in your AWS account: Postgres runs on RDS, in a VPC of its own, and runners run on ECS Fargate in the same VPC. A load balancer serves each pool’s gateway, so a Lambda function, a container or a Worker calls the rooms by id.
import * as ClusterAWS from "@alchemy.run/effect-cluster/AWS";import * as Layer from "effect/Layer";
export const Database = ClusterAWS.Database("Cluster");
export const Default = ClusterAWS.EcsPool("Default", { replicas: 2 }).pipe( Layer.provide(Database),);Install @alchemy.run/aws and finish AWS setup.
- class
- db.m7g.large
- replicas
- 3
The database
Section titled “The database”ClusterAWS.Database creates a VPC across two Availability Zones, an RDS Postgres instance in it, and one security group every runner joins. That group reaches Postgres and the other runners; nothing else does.
import * as ClusterAWS from "@alchemy.run/effect-cluster/AWS";
export const Database = ClusterAWS.Database("Cluster", { instanceClass: "db.m7g.large", multiAZ: true, allocatedStorage: 100,});A new RDS instance takes 10 to 15 minutes to create.
The pool
Section titled “The pool”EcsPool runs the pool as an ECS service on Fargate, in the database’s VPC:
import * as ClusterAWS from "@alchemy.run/effect-cluster/AWS";import * as Layer from "effect/Layer";
export const Database = ClusterAWS.Database("Cluster");
export const Default = ClusterAWS.EcsPool("Default", { replicas: 3, cpu: 1024, memory: 2048, architecture: "ARM64",}).pipe(Layer.provide(Database));Each pool gets an internet-facing Application Load Balancer in front of its gateway. The runners only take gateway traffic from it, and the gateway checks every call’s token.
Call it from a Lambda
Section titled “Call it from a Lambda”import * as Lambda from "@alchemy.run/aws/Lambda";import * as Effect from "effect/Effect";import * as HttpServerResponse from "effect/http/HttpServerResponse";import { Room } from "./Room.ts";
export default class Api extends Lambda.Function<Api>()( "Api", { main: import.meta.url, functionUrl: true }, Effect.gen(function* () { const rooms = yield* Room; return { fetch: Effect.gen(function* () { const lobby = yield* rooms.getByName("lobby"); return yield* HttpServerResponse.json({ members: yield* lobby.Join({ name: "sam" }) }); }).pipe(Effect.orDie), }; }),) {}Every option, with its default, is in the reference: Database and EcsPool.