-
Notifications
You must be signed in to change notification settings - Fork 2
update cached client #408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update cached client #408
Changes from all commits
ef6c61c
252d2d0
617711f
1a3ca77
4a0af12
80350fe
b7185b4
81a98ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| /** @jest-environment node */ | ||
| import { getClient, resetClient } from '@utils/mongodb/mongoClient.mjs'; | ||
| import { MongoClient } from 'mongodb'; | ||
|
|
||
| describe('getClient', () => { | ||
| beforeEach(async () => { | ||
| await resetClient(); | ||
| jest.restoreAllMocks(); | ||
| }); | ||
|
|
||
| it('should throw an error if MONGODB_URI is missing', async () => { | ||
| const originalUri = process.env.MONGODB_URI; | ||
| delete process.env.MONGODB_URI; | ||
|
|
||
| await resetClient(); | ||
|
|
||
| await expect(getClient()).rejects.toThrow( | ||
| 'Missing MONGODB_URI environment variable.' | ||
| ); | ||
|
|
||
| process.env.MONGODB_URI = originalUri; | ||
| }); | ||
|
|
||
| it('should return the same instance on multiple calls', async () => { | ||
| const mockDb = { db: jest.fn() }; | ||
| const spy = jest | ||
| .spyOn(MongoClient.prototype, 'connect') | ||
| .mockResolvedValue(mockDb as any); | ||
|
|
||
|
michelleyeoh marked this conversation as resolved.
|
||
| const c1 = await getClient(); | ||
| const c2 = await getClient(); | ||
|
|
||
| expect(c1).toBe(c2); | ||
| expect(spy).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
michelleyeoh marked this conversation as resolved.
|
||
|
|
||
| it('should dedupe concurrent callers using cachedPromise', async () => { | ||
| const mockDb = { db: jest.fn() }; | ||
| const spy = jest | ||
| .spyOn(MongoClient.prototype, 'connect') | ||
| .mockResolvedValue(mockDb as any); | ||
| const [c1, c2] = await Promise.all([getClient(), getClient()]); | ||
| expect(c1).toBe(c2); | ||
| expect(spy).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
|
||
| it('should retry after a failed connection', async () => { | ||
| const spy = jest | ||
| .spyOn(MongoClient.prototype, 'connect') | ||
| .mockRejectedValueOnce(new Error('Network Fail')) | ||
| .mockResolvedValueOnce({ db: jest.fn() } as any); | ||
|
|
||
|
michelleyeoh marked this conversation as resolved.
|
||
| await expect(getClient()).rejects.toThrow('Network Fail'); | ||
|
|
||
| await expect(getClient()).resolves.toBeDefined(); | ||
| expect(spy).toHaveBeenCalledTimes(2); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,15 +1,41 @@ | ||||||||||||||||||
| import { MongoClient } from 'mongodb'; | ||||||||||||||||||
|
|
||||||||||||||||||
| const uri = process.env.MONGODB_URI; | ||||||||||||||||||
| let cachedClient = null; | ||||||||||||||||||
| let cachedPromise = null; | ||||||||||||||||||
|
|
||||||||||||||||||
| export async function getClient() { | ||||||||||||||||||
| const uri = process.env.MONGODB_URI; | ||||||||||||||||||
| if (!uri) { | ||||||||||||||||||
| throw new Error('Missing MONGODB_URI environment variable.'); | ||||||||||||||||||
| } | ||||||||||||||||||
|
michelleyeoh marked this conversation as resolved.
|
||||||||||||||||||
|
|
||||||||||||||||||
| if (cachedClient) { | ||||||||||||||||||
| return cachedClient; | ||||||||||||||||||
| } | ||||||||||||||||||
| const client = new MongoClient(uri); | ||||||||||||||||||
| cachedClient = client; | ||||||||||||||||||
| return cachedClient; | ||||||||||||||||||
|
|
||||||||||||||||||
| if (!cachedPromise) { | ||||||||||||||||||
| const client = new MongoClient(uri); | ||||||||||||||||||
| cachedPromise = client | ||||||||||||||||||
| .connect() | ||||||||||||||||||
| .then((connectedClient) => { | ||||||||||||||||||
| cachedClient = connectedClient; | ||||||||||||||||||
| return connectedClient; | ||||||||||||||||||
| }) | ||||||||||||||||||
| .catch((error) => { | ||||||||||||||||||
| client.close().catch(() => {}); | ||||||||||||||||||
|
Comment on lines
+24
to
+25
|
||||||||||||||||||
| .catch((error) => { | |
| client.close().catch(() => {}); | |
| .catch(async (error) => { | |
| try { | |
| await client.close(); | |
| } catch { | |
| // Ignore errors while closing the client | |
| } |
Uh oh!
There was an error while loading. Please reload this page.