6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
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' ;
13
10
import { BundleActionCache } from './action-cache' ;
14
11
import { maxWorkers } from './environment-options' ;
15
12
import { I18nOptions } from './i18n-options' ;
16
13
import { InlineOptions , ProcessBundleOptions , ProcessBundleResult } from './process-bundle' ;
17
14
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' ) ;
21
16
22
17
export class BundleActionExecutor {
23
- private largeWorker ?: JestWorker ;
24
- private smallWorker ?: JestWorker ;
18
+ private workerPool ?: Piscina ;
25
19
private cache ?: BundleActionCache ;
26
20
27
21
constructor (
28
22
private workerOptions : { cachePath ?: string ; i18n : I18nOptions } ,
29
23
integrityAlgorithm ?: string ,
30
- private readonly sizeThreshold = 32 * 1024 ,
31
24
) {
32
25
if ( workerOptions . cachePath ) {
33
26
this . cache = new BundleActionCache ( workerOptions . cachePath , integrityAlgorithm ) ;
34
27
}
35
28
}
36
29
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 ;
57
33
}
58
34
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
+ } ) ;
68
41
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 ;
76
43
}
77
44
78
45
async process ( action : ProcessBundleOptions ) : Promise < ProcessBundleResult > {
@@ -89,7 +56,7 @@ export class BundleActionExecutor {
89
56
} catch { }
90
57
}
91
58
92
- return this . executeAction < ProcessBundleResult > ( 'process' , action ) ;
59
+ return this . ensureWorkerPool ( ) . run ( action , { name : 'process' } ) ;
93
60
}
94
61
95
62
processAll ( actions : Iterable < ProcessBundleOptions > ) : AsyncIterable < ProcessBundleResult > {
@@ -99,7 +66,7 @@ export class BundleActionExecutor {
99
66
async inline (
100
67
action : InlineOptions ,
101
68
) : Promise < { file : string ; diagnostics : { type : string ; message : string } [ ] ; count : number } > {
102
- return this . executeAction ( 'inlineLocales' , action ) ;
69
+ return this . ensureWorkerPool ( ) . run ( action , { name : 'inlineLocales' } ) ;
103
70
}
104
71
105
72
inlineAll ( actions : Iterable < InlineOptions > ) {
@@ -129,15 +96,6 @@ export class BundleActionExecutor {
129
96
}
130
97
131
98
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 ( ) ;
142
100
}
143
101
}
0 commit comments