66 * found in the LICENSE file at https://angular.io/license
77 */
88
9- import { Worker as JestWorker } from 'jest-worker' ;
10- import * as os from 'os' ;
11- import * as path from 'path' ;
12- import { serialize } from 'v8' ;
9+ import Piscina from 'piscina' ;
1310import { BundleActionCache } from './action-cache' ;
1411import { maxWorkers } from './environment-options' ;
1512import { I18nOptions } from './i18n-options' ;
1613import { InlineOptions , ProcessBundleOptions , ProcessBundleResult } from './process-bundle' ;
1714
18- let workerFile = require . resolve ( './process-bundle' ) ;
19- workerFile =
20- path . extname ( workerFile ) === '.ts' ? require . resolve ( './process-bundle-bootstrap' ) : workerFile ;
15+ const workerFile = require . resolve ( './process-bundle' ) ;
2116
2217export class BundleActionExecutor {
23- private largeWorker ?: JestWorker ;
24- private smallWorker ?: JestWorker ;
18+ private workerPool ?: Piscina ;
2519 private cache ?: BundleActionCache ;
2620
2721 constructor (
2822 private workerOptions : { cachePath ?: string ; i18n : I18nOptions } ,
2923 integrityAlgorithm ?: string ,
30- private readonly sizeThreshold = 32 * 1024 ,
3124 ) {
3225 if ( workerOptions . cachePath ) {
3326 this . cache = new BundleActionCache ( workerOptions . cachePath , integrityAlgorithm ) ;
3427 }
3528 }
3629
37- private static executeMethod < O > ( worker : JestWorker , method : string , input : unknown ) : Promise < O > {
38- return ( worker as unknown as Record < string , ( i : unknown ) => Promise < O > > ) [ method ] ( input ) ;
39- }
40-
41- private ensureLarge ( ) : JestWorker {
42- if ( this . largeWorker ) {
43- return this . largeWorker ;
44- }
45-
46- // larger files are processed in a separate process to limit memory usage in the main process
47- return ( this . largeWorker = new JestWorker ( workerFile , {
48- exposedMethods : [ 'process' , 'inlineLocales' ] ,
49- setupArgs : [ [ ...serialize ( this . workerOptions ) ] ] ,
50- numWorkers : maxWorkers ,
51- } ) ) ;
52- }
53-
54- private ensureSmall ( ) : JestWorker {
55- if ( this . smallWorker ) {
56- return this . smallWorker ;
30+ private ensureWorkerPool ( ) : Piscina {
31+ if ( this . workerPool ) {
32+ return this . workerPool ;
5733 }
5834
59- // small files are processed in a limited number of threads to improve speed
60- // The limited number also prevents a large increase in memory usage for an otherwise short operation
61- return ( this . smallWorker = new JestWorker ( workerFile , {
62- exposedMethods : [ 'process' , 'inlineLocales' ] ,
63- setupArgs : [ this . workerOptions ] ,
64- numWorkers : os . cpus ( ) . length < 2 ? 1 : 2 ,
65- enableWorkerThreads : true ,
66- } ) ) ;
67- }
35+ this . workerPool = new Piscina ( {
36+ filename : workerFile ,
37+ name : 'process' ,
38+ workerData : this . workerOptions ,
39+ maxThreads : maxWorkers ,
40+ } ) ;
6841
69- private executeAction < O > ( method : string , action : { code : string } ) : Promise < O > {
70- // code.length is not an exact byte count but close enough for this
71- if ( action . code . length > this . sizeThreshold ) {
72- return BundleActionExecutor . executeMethod < O > ( this . ensureLarge ( ) , method , action ) ;
73- } else {
74- return BundleActionExecutor . executeMethod < O > ( this . ensureSmall ( ) , method , action ) ;
75- }
42+ return this . workerPool ;
7643 }
7744
7845 async process ( action : ProcessBundleOptions ) : Promise < ProcessBundleResult > {
@@ -89,7 +56,7 @@ export class BundleActionExecutor {
8956 } catch { }
9057 }
9158
92- return this . executeAction < ProcessBundleResult > ( 'process' , action ) ;
59+ return this . ensureWorkerPool ( ) . run ( action , { name : 'process' } ) ;
9360 }
9461
9562 processAll ( actions : Iterable < ProcessBundleOptions > ) : AsyncIterable < ProcessBundleResult > {
@@ -99,7 +66,7 @@ export class BundleActionExecutor {
9966 async inline (
10067 action : InlineOptions ,
10168 ) : Promise < { file : string ; diagnostics : { type : string ; message : string } [ ] ; count : number } > {
102- return this . executeAction ( 'inlineLocales' , action ) ;
69+ return this . ensureWorkerPool ( ) . run ( action , { name : 'inlineLocales' } ) ;
10370 }
10471
10572 inlineAll ( actions : Iterable < InlineOptions > ) {
@@ -129,15 +96,6 @@ export class BundleActionExecutor {
12996 }
13097
13198 stop ( ) : void {
132- // Floating promises are intentional here
133- // https://github.com/facebook/jest/tree/56079a5aceacf32333089cea50c64385885fee26/packages/jest-worker#end
134- if ( this . largeWorker ) {
135- // eslint-disable-next-line @typescript-eslint/no-floating-promises
136- this . largeWorker . end ( ) ;
137- }
138- if ( this . smallWorker ) {
139- // eslint-disable-next-line @typescript-eslint/no-floating-promises
140- this . smallWorker . end ( ) ;
141- }
99+ void this . workerPool ?. destroy ( ) ;
142100 }
143101}
0 commit comments