Skip to content

Commit

Permalink
throw isntead of silently succeeding
Browse files Browse the repository at this point in the history
  • Loading branch information
casey-chow committed Sep 20, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent f562895 commit f1b643b
Showing 3 changed files with 12 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/ReplicaManager.ts
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ export class ReplicaManager {
await Promise.all(this._replicaClients.map((client) => client.$disconnect()))
}

pickReplica(): PrismaClient | undefined {
pickReplica(): PrismaClient {
return this._replicaClients[Math.floor(Math.random() * this._replicaClients.length)]
}
}
4 changes: 3 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@ export const readReplicas = (options: ReplicasOptions, configureReplicaClient?:
replicaUrls = [replicaUrls]
} else if (!Array.isArray(replicaUrls)) {
throw new Error(`Replica URLs must be a string or list of strings`)
} else if (replicaUrls.length === 0) {
throw new Error(`At least one replica URL must be specified`)
}

const replicaManager = new ReplicaManager({
@@ -69,7 +71,7 @@ export const readReplicas = (options: ReplicasOptions, configureReplicaClient?:
return query(args)
}
if (readOperations.includes(operation)) {
const replica = replicaManager.pickReplica() ?? client
const replica = replicaManager.pickReplica()
if (model) {
return replica[model][operation](args)
}
38 changes: 8 additions & 30 deletions tests/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import execa from 'execa'
// @ts-ignore
import type { PrismaClient } from './client'
import { readReplicas } from '..'
import type { PrismaClient } from './client'

type LogEntry = { server: 'primary' | 'replica'; operation: string }

@@ -47,44 +47,22 @@ beforeAll(async () => {
await execa('pnpm', ['prisma', 'db', 'push', '--schema', 'tests/prisma/schema.prisma'], {
cwd: __dirname,
})

;[basePrisma, prisma] = createPrisma()
})

beforeEach(async () => {
logs = []
})

test('query is executed against primary when no replicas are configured', async () => {
const emptyPrisma = basePrisma
.$extends(
readReplicas(
{
url: [],
},
(client) =>
(client as PrismaClient).$extends({
query: {
$allOperations({ args, operation, query }) {
logs.push({ server: 'replica', operation })
return query(args)
},
},
}),
),
test('client throws an error when given an empty read replica list', async () => {
const createInstance = () =>
basePrisma.$extends(
readReplicas({
url: [],
}),
)
.$extends({
query: {
$allOperations({ args, operation, query }) {
logs.push({ server: 'primary', operation })
return query(args)
},
},
})

await emptyPrisma.user.findMany()

expect(logs).toEqual([{ server: 'primary', operation: 'findMany' }])
expect(createInstance).toThrowError('At least one replica URL must be specified')
})

test('read query is executed against replica', async () => {

0 comments on commit f1b643b

Please sign in to comment.