Created
June 14, 2023 01:18
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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