Skip to content

Commit e625dea

Browse files
[Performance] Memoize isWsl result
This change memoizes the result of the `isWsl` function in `@shopify/cli-kit`. Since `isWsl` involves a dynamic import and potential filesystem checks, memoizing the promise ensures that these operations are only performed once per process. This is particularly beneficial in high-frequency paths like analytics collection. A `_resetIsWsl` function is also provided for test isolation. Added regression tests in `system.test.ts`.
1 parent 05d0eaf commit e625dea

2 files changed

Lines changed: 47 additions & 3 deletions

File tree

packages/cli-kit/src/public/node/system.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,32 @@ describe('readStdinString', () => {
393393
await expect(got).rejects.toThrow('Stdin input exceeded the maximum allowed size.')
394394
})
395395
})
396+
397+
describe('isWsl', () => {
398+
test('memoizes the result', async () => {
399+
// Given
400+
// We need to use the real isWsl but since it's already exported from system.js
401+
// we can check if it returns the same promise.
402+
403+
// When
404+
const promise1 = system.isWsl()
405+
const promise2 = system.isWsl()
406+
407+
// Then
408+
expect(promise1).toBe(promise2)
409+
await promise1
410+
})
411+
412+
test('can be reset', async () => {
413+
// Given
414+
const promise1 = system.isWsl()
415+
416+
// When
417+
;(system as any)._resetIsWsl()
418+
const promise2 = system.isWsl()
419+
420+
// Then
421+
expect(promise1).not.toBe(promise2)
422+
await Promise.all([promise1, promise2])
423+
})
424+
})

packages/cli-kit/src/public/node/system.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,29 @@ export function isCI(): boolean {
354354
return isTruthy(process.env.CI)
355355
}
356356

357+
/**
358+
* Memoized value for the WSL check.
359+
*/
360+
let memoizedIsWsl: Promise<boolean> | undefined
361+
357362
/**
358363
* Check if the current environment is a WSL environment.
359364
*
360365
* @returns True if the current environment is a WSL environment.
361366
*/
362-
export async function isWsl(): Promise<boolean> {
363-
const wsl = await import('is-wsl')
364-
return wsl.default
367+
export function isWsl(): Promise<boolean> {
368+
return (memoizedIsWsl ??= (async () => {
369+
const wsl = await import('is-wsl')
370+
return wsl.default
371+
})())
372+
}
373+
374+
/**
375+
* Resets the memoized value of isWsl.
376+
* This is only used for testing.
377+
*/
378+
export function _resetIsWsl() {
379+
memoizedIsWsl = undefined
365380
}
366381

367382
/**

0 commit comments

Comments
 (0)