diff --git a/bun.lock b/bun.lock index 3fac1ae..bda21fd 100644 --- a/bun.lock +++ b/bun.lock @@ -145,6 +145,7 @@ "@metorial-services/forge-client": "^1.0.4", "@prisma/adapter-pg": "^7.2.0", "@prisma/client": "^7.2.0", + "@prisma/extension-read-replicas": "^0.5.0", "@sentry/bun": "^10.38.0", "@sentry/cli": "^3.2.0", "date-fns": "^4.1.0", @@ -702,6 +703,8 @@ "@prisma/engines-version": ["@prisma/engines-version@7.3.0-16.9d6ad21cbbceab97458517b147a6a09ff43aa735", "", {}, "sha512-IH2va2ouUHihyiTTRW889LjKAl1CusZOvFfZxCDNpjSENt7g2ndFsK0vdIw/72v7+jCN6YgkHmdAP/BI7SDgyg=="], + "@prisma/extension-read-replicas": ["@prisma/extension-read-replicas@0.5.0", "", { "peerDependencies": { "@prisma/client": "^7.0.0" } }, "sha512-t0kLjqFMte4wwGrZFhya4iFoyoOY4kjlyyE60WXZL66PqP6PcBpW/35eKb/3UcxgjJxcDlaJKfmGokFLOyafiQ=="], + "@prisma/fetch-engine": ["@prisma/fetch-engine@7.3.0", "", { "dependencies": { "@prisma/debug": "7.3.0", "@prisma/engines-version": "7.3.0-16.9d6ad21cbbceab97458517b147a6a09ff43aa735", "@prisma/get-platform": "7.3.0" } }, "sha512-Mm0F84JMqM9Vxk70pzfNpGJ1lE4hYjOeLMu7nOOD1i83nvp8MSAcFYBnHqLvEZiA6onUR+m8iYogtOY4oPO5lQ=="], "@prisma/generator": ["@prisma/generator@7.3.0", "", {}, "sha512-PRjhVXu+oNLY2PDahZRRmOgctT17rtKCp9+2odfw2GIqHhdOTeGhX9scGNPsZujiGRz6txJwvor24FdxZfEWLw=="], diff --git a/service/package.json b/service/package.json index d410b2a..a9c23d1 100644 --- a/service/package.json +++ b/service/package.json @@ -57,6 +57,7 @@ "@metorial-services/forge-client": "^1.0.4", "@prisma/adapter-pg": "^7.2.0", "@prisma/client": "^7.2.0", + "@prisma/extension-read-replicas": "^0.5.0", "@sentry/bun": "^10.38.0", "@sentry/cli": "^3.2.0", "date-fns": "^4.1.0", diff --git a/service/src/db.ts b/service/src/db.ts index a52a728..654663c 100644 --- a/service/src/db.ts +++ b/service/src/db.ts @@ -1,10 +1,35 @@ import type { FunctionBayLayer, FunctionBayRuntimeSpec } from '@function-bay/types'; import { PrismaPg } from '@prisma/adapter-pg'; +import { readReplicas } from '@prisma/extension-read-replicas'; import { PrismaClient } from '../prisma/generated/client'; -let adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }); +let mainAdapter = new PrismaPg({ + connectionString: process.env.DATABASE_URL +}); -export let db = new PrismaClient({ adapter }); +let replicaAdapter = process.env.DATABASE_URL_READER + ? new PrismaPg({ + connectionString: process.env.DATABASE_URL_READER + }) + : undefined; + +let replicaClient = replicaAdapter ? new PrismaClient({ adapter: replicaAdapter }) : undefined; + +let baseClient = new PrismaClient({ + adapter: mainAdapter, + transactionOptions: { + maxWait: 10000, + timeout: 12000 + } +}); + +if (replicaClient) { + baseClient = baseClient.$extends( + readReplicas({ replicas: [replicaClient] }) + ) as any as PrismaClient; +} + +export let db = baseClient; declare global { namespace PrismaJson { diff --git a/service/src/init.ts b/service/src/init.ts index c75989f..42ceb09 100644 --- a/service/src/init.ts +++ b/service/src/init.ts @@ -1,5 +1,9 @@ if (!process.env.DATABASE_URL) { process.env.DATABASE_URL = `postgres://${process.env.DATABASE_USERNAME}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_NAME}?schema=public&sslmode=no-verify&connection_limit=20`; + + if (process.env.DATABASE_READER === 'true') { + process.env.DATABASE_URL_READER = `postgres://${process.env.DATABASE_USERNAME}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST?.replace('.cluster-', '.cluster-ro-')}:${process.env.DATABASE_PORT}/${process.env.DATABASE_NAME}?schema=public&sslmode=no-verify&connection_limit=20`; + } } if (!process.env.REDIS_URL) {