1- import JestWorker from 'jest-worker'
1+ import Worker from 'jest-worker'
22import * as path from 'path'
3+ import os from 'os'
34import { execOnce } from '../../../lib/utils'
45import ImageData from './image_data'
56
7+ const CORES = ( os . cpus ( ) || { length : 1 } ) . length
8+
69const getWorker = execOnce (
710 ( ) =>
8- new JestWorker ( path . resolve ( __dirname , 'impl' ) , {
11+ new Worker ( path . resolve ( __dirname , 'impl' ) , {
912 enableWorkerThreads : true ,
1013 } )
1114)
1215
16+ // Jest-worker currently holds the latest execution's arguments and return
17+ // value in its internal queue of every worker in the pool, due to some
18+ // uncollected closures and references. This increases the memory use
19+ // tremendously so we are calling the no-op method N times so each worker
20+ // will replace the references of arguments and return value, which triggers
21+ // the GC automatically to reduce memory usage.
22+ function triggerWorkerGC ( ) {
23+ const worker : typeof import ( './impl' ) = getWorker ( ) as any
24+ for ( let i = 0 ; i < CORES ; i ++ ) {
25+ worker . noop ( )
26+ }
27+ }
28+
1329export async function decodeBuffer ( buffer : Buffer ) : Promise < ImageData > {
1430 const worker : typeof import ( './impl' ) = getWorker ( ) as any
15- return ImageData . from ( await worker . decodeBuffer ( buffer ) )
31+ const data = ImageData . from ( await worker . decodeBuffer ( buffer ) )
32+ triggerWorkerGC ( )
33+ return data
1634}
1735
1836export async function rotate (
1937 image : ImageData ,
2038 numRotations : number
2139) : Promise < ImageData > {
2240 const worker : typeof import ( './impl' ) = getWorker ( ) as any
23- return ImageData . from ( await worker . rotate ( image , numRotations ) )
41+ const data = ImageData . from ( await worker . rotate ( image , numRotations ) )
42+ triggerWorkerGC ( )
43+ return data
2444}
2545
2646export async function resize (
2747 image : ImageData ,
2848 { width } : { width : number }
2949) : Promise < ImageData > {
3050 const worker : typeof import ( './impl' ) = getWorker ( ) as any
31- return ImageData . from ( await worker . resize ( image , { width } ) )
51+ const data = ImageData . from ( await worker . resize ( image , { width } ) )
52+ triggerWorkerGC ( )
53+ return data
3254}
3355
3456export async function encodeJpeg (
@@ -37,7 +59,9 @@ export async function encodeJpeg(
3759) : Promise < Buffer > {
3860 const worker : typeof import ( './impl' ) = getWorker ( ) as any
3961 const o = await worker . encodeJpeg ( image , { quality } )
40- return Buffer . from ( o )
62+ const data = Buffer . from ( o )
63+ triggerWorkerGC ( )
64+ return data
4165}
4266
4367export async function encodeWebp (
@@ -46,11 +70,15 @@ export async function encodeWebp(
4670) : Promise < Buffer > {
4771 const worker : typeof import ( './impl' ) = getWorker ( ) as any
4872 const o = await worker . encodeWebp ( image , { quality } )
49- return Buffer . from ( o )
73+ const data = Buffer . from ( o )
74+ triggerWorkerGC ( )
75+ return data
5076}
5177
5278export async function encodePng ( image : ImageData ) : Promise < Buffer > {
5379 const worker : typeof import ( './impl' ) = getWorker ( ) as any
5480 const o = await worker . encodePng ( image )
55- return Buffer . from ( o )
81+ const data = Buffer . from ( o )
82+ triggerWorkerGC ( )
83+ return data
5684}
0 commit comments