Skip to content

Instantly share code, notes, and snippets.

@djdmbrwsk
Created June 14, 2023 01:18
Show Gist options
  • Save djdmbrwsk/46673aa7f6474383742924e1b594cef2 to your computer and use it in GitHub Desktop.
Save djdmbrwsk/46673aa7f6474383742924e1b594cef2 to your computer and use it in GitHub Desktop.
Prisma extension that will automatically disconnect the Prisma client after a period of inactivity.
import { Prisma, PrismaClient } from '@prisma/client';
type PrismaClientWithQueryLogEvents = PrismaClient<{
log: {
level: 'query';
emit: 'event';
}[];
}>;
type PrismaClientIdleDisconnectEx = {
$$idleDisconnectTimeoutId?: NodeJS.Timeout;
};
/**
* Prisma extension that will automatically disconnect the Prisma client after a period of inactivity.
*
* **NOTE:** This extension requires you configure your PrismaClient to emit query log events.
*
* ```ts
* // Example setup:
* export const prisma = new PrismaClient({
* log: [{ level: 'query', emit: 'event' }],
* }).$extends(prismaUtils.idleDisconnect);
*
* prisma.$configureIdleDisconnect(5 * 60000);
* ```
*
* Also confirm you've opted into extensions in your `schema.prisma` file:
* ```
* generator client {
* provider = "prisma-client-js"
* previewFeatures = ["clientExtensions"]
* // ...
* }
* ```
*
*/
export const idleDisconnect = Prisma.defineExtension({
client: {
$configureIdleDisconnect(idleDisconnectTimeoutMs: number, debug = false) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const log = (...vals: any) => {
debug && console.log('[idleDisconnect][DEBUG]', ...vals);
};
// Get current prisma instance and extend with typing specific to this extension
const prisma = Prisma.getExtensionContext(this);
const prismaEx = prisma as unknown as typeof prisma & {
$on: PrismaClientWithQueryLogEvents['$on'];
} & PrismaClientIdleDisconnectEx;
prismaEx.$on('query', (e) => {
log(`Prisma 'query' log triggered:`, e);
// For each call to the Prisma client numerous 'query' events are emitted. The last one is the COMMIT query.
if (e.query === 'COMMIT') {
log('COMMIT query detected');
if (prismaEx.$$idleDisconnectTimeoutId) {
log('Clearing existing idle disconnect timeout');
clearTimeout(prismaEx.$$idleDisconnectTimeoutId);
}
log(
`Creating an idle disconnect timeout for ${idleDisconnectTimeoutMs}ms from now`,
);
prismaEx.$$idleDisconnectTimeoutId = setTimeout(() => {
log('Disconnecting Prisma client');
prismaEx.$disconnect(); // No await here, but fire-and-forget should be fine
}, idleDisconnectTimeoutMs);
}
});
},
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment