Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
example: hyperdrive initial progress
Browse files Browse the repository at this point in the history
  • Loading branch information
thdxr committed Sep 21, 2024
1 parent 7e69488 commit cbb8674
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 0 deletions.
4 changes: 4 additions & 0 deletions examples/hyperdrive/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@


# sst
.sst
3 changes: 3 additions & 0 deletions examples/hyperdrive/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# sst
.sst
3 changes: 3 additions & 0 deletions examples/hyperdrive/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM cloudflare/cloudflared:latest

CMD ["tunnel", "run"]
Binary file added examples/hyperdrive/bun.lockb
Binary file not shown.
29 changes: 29 additions & 0 deletions examples/hyperdrive/lambda.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import postgres from "postgres";
import { Resource } from "sst";

const sql = postgres(
`postgres://${Resource.Postgres.username}:${Resource.Postgres.password}@${Resource.Postgres.host}:${Resource.Postgres.port}/${Resource.Postgres.database}`,
);

export async function handler() {
try {
// A very simple test query
const now = Date.now();
const result = await sql`select * from pg_tables limit 10`;
const delay = Date.now() - now;
return {
statusCode: 200,
body: JSON.stringify({
result,
delay,
}),
};
} catch (e) {
return {
statusCode: 200,
body: JSON.stringify({
error: e.message,
}),
};
}
}
10 changes: 10 additions & 0 deletions examples/hyperdrive/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "hyperdrive",
"version": "0.0.0",
"type": "module",
"dependencies": {
"@cloudflare/workers-types": "^4.20240919.0",
"postgres": "^3.4.4",
"sst": "3.1.29"
}
}
39 changes: 39 additions & 0 deletions examples/hyperdrive/sst-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* This file is auto-generated by SST. Do not edit. */
/* tslint:disable */
/* eslint-disable */
import "sst"
export {}
import "sst"
declare module "sst" {
export interface Resource {
"Cloudflared": {
"service": string
"type": "sst.aws.Service"
}
"Lambda": {
"name": string
"type": "sst.aws.Function"
"url": string
}
"Postgres": {
"clusterArn": string
"database": string
"host": string
"password": string
"port": number
"secretArn": string
"type": "sst.aws.Postgres"
"username": string
}
"Vpc": {
"type": "sst.aws.Vpc"
}
}
}
// cloudflare
import * as cloudflare from "@cloudflare/workers-types";
declare module "sst" {
export interface Resource {
"Worker": cloudflare.Service
}
}
103 changes: 103 additions & 0 deletions examples/hyperdrive/sst.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "hyperdrive",
removal: input?.stage === "production" ? "retain" : "remove",
home: "aws",
providers: { cloudflare: "5.39.0", random: "4.16.5" },
};
},
async run() {
// THIS EXAMPLE IS NOT READY YET

const vpc = new sst.aws.Vpc("Vpc", {
nat: "managed",
});
const cluster = new sst.aws.Cluster("Cluster", { vpc });
const postgres = new sst.aws.Postgres("Postgres", { vpc });
const domain = "sst.cheap";
const zone = cloudflare.getZoneOutput({ name: domain });

const tunnelSecret = new random.RandomString("TunnelSecret", {
length: 32,
});
const tunnel = new cloudflare.Tunnel("Tunnel", {
name: `${$app.name}-${$app.stage}-tunnel`,
secret: tunnelSecret.result.apply((v) =>
Buffer.from(v).toString("base64"),
),
accountId: sst.cloudflare.DEFAULT_ACCOUNT_ID,
});
new cloudflare.TunnelConfig("TunnelConfig", {
accountId: sst.cloudflare.DEFAULT_ACCOUNT_ID,
tunnelId: tunnel.id,
config: {
ingressRules: [
{
service: $interpolate`tcp://${postgres.host}:${postgres.port}`,
},
],
},
});
const record = new cloudflare.Record("TunnelRecord", {
name: $interpolate`hypedrive.${domain}`,
zoneId: zone.id,
type: "CNAME",
value: $interpolate`${tunnel.id}.cfargotunnel.com`,
proxied: true,
});
const hyperdriveConfig = new cloudflare.HyperdriveConfig(
"HyperdriveConfig",
{
name: `${$app.name}-${$app.stage}-config`,
accountId: sst.cloudflare.DEFAULT_ACCOUNT_ID,
origin: {
host: record.name,
user: postgres.username,
password: postgres.password,
database: postgres.database,
accessClientId: "dummy",
accessClientSecret: "dummy",
scheme: "postgres",
},
},
);
cluster.addService("Cloudflared", {
environment: {
TUNNEL_TOKEN: tunnel.tunnelToken,
},
});
const worker = new sst.cloudflare.Worker("Worker", {
handler: "worker.ts",
url: true,
transform: {
worker: {
placements: [
{
mode: "smart",
},
],
hyperdriveConfigBindings: [
{
binding: "HYPERDRIVE",
id: "7c064ebd005348329a38106b076d579d",
},
],
},
},
});

const lambda = new sst.aws.Function("Lambda", {
handler: "lambda.handler",
link: [postgres],
vpc,
url: true,
});

return {
worker: worker.url,
lambda: lambda.url,
};
},
});
5 changes: 5 additions & 0 deletions examples/hyperdrive/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"esModuleInterop": true
}
}
33 changes: 33 additions & 0 deletions examples/hyperdrive/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import postgres from "postgres";
import { Hyperdrive, ExecutionContext } from "@cloudflare/workers-types";

export interface Env {
// If you set another name in wrangler.toml as the value for 'binding',
// replace "HYPERDRIVE" with the variable name you defined.
HYPERDRIVE: Hyperdrive;
}

export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
// NOTE: if `prepare: false` is passed when connecting, performance will
// be slower but still correctly supported.
const sql = postgres(env.HYPERDRIVE.connectionString);

try {
// A very simple test query
const now = Date.now();
const result = await sql`select * from pg_tables limit 10`;
const delay = Date.now() - now;

// Clean up the client, ensuring we don't kill the worker before that is
// completed.
ctx.waitUntil(sql.end());

// Return result rows as JSON
return Response.json({ delay, result });
} catch (e) {
console.log(e);
return Response.json({ error: e.message }, { status: 500 });
}
},
};

0 comments on commit cbb8674

Please sign in to comment.