"Fossies" - the Fresh Open Source Software Archive

Member "angular-cli-8.3.23/packages/angular_devkit/build_angular/src/browser/action-executor.ts" (15 Jan 2020, 3610 Bytes) of package /linux/www/angular-cli-8.3.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TypeScript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /**
    2  * @license
    3  * Copyright Google Inc. All Rights Reserved.
    4  *
    5  * Use of this source code is governed by an MIT-style license that can be
    6  * found in the LICENSE file at https://angular.io/license
    7  */
    8 import JestWorker from 'jest-worker';
    9 import * as os from 'os';
   10 import * as path from 'path';
   11 import { ProcessBundleOptions, ProcessBundleResult } from '../utils/process-bundle';
   12 import { BundleActionCache } from './action-cache';
   13 
   14 let workerFile = require.resolve('../utils/process-bundle');
   15 workerFile =
   16   path.extname(workerFile) === '.ts'
   17     ? require.resolve('../utils/process-bundle-bootstrap')
   18     : workerFile;
   19 
   20 export class BundleActionExecutor {
   21   private largeWorker?: JestWorker;
   22   private smallWorker?: JestWorker;
   23   private cache: BundleActionCache;
   24 
   25   constructor(
   26     private workerOptions: unknown,
   27     integrityAlgorithm?: string,
   28     private readonly sizeThreshold = 32 * 1024,
   29   ) {
   30     this.cache = new BundleActionCache(integrityAlgorithm);
   31   }
   32 
   33   private static executeMethod<O>(worker: JestWorker, method: string, input: unknown): Promise<O> {
   34     return ((worker as unknown) as Record<string, (i: unknown) => Promise<O>>)[method](input);
   35   }
   36 
   37   private ensureLarge(): JestWorker {
   38     if (this.largeWorker) {
   39       return this.largeWorker;
   40     }
   41 
   42     // larger files are processed in a separate process to limit memory usage in the main process
   43     return (this.largeWorker = new JestWorker(workerFile, {
   44       exposedMethods: ['process'],
   45       setupArgs: [this.workerOptions],
   46     }));
   47   }
   48 
   49   private ensureSmall(): JestWorker {
   50     if (this.smallWorker) {
   51       return this.smallWorker;
   52     }
   53 
   54     // small files are processed in a limited number of threads to improve speed
   55     // The limited number also prevents a large increase in memory usage for an otherwise short operation
   56     return (this.smallWorker = new JestWorker(workerFile, {
   57       exposedMethods: ['process'],
   58       setupArgs: [this.workerOptions],
   59       numWorkers: os.cpus().length < 2 ? 1 : 2,
   60       // Will automatically fallback to processes if not supported
   61       enableWorkerThreads: true,
   62     }));
   63   }
   64 
   65   private executeAction<O>(method: string, action: { code: string }): Promise<O> {
   66     // code.length is not an exact byte count but close enough for this
   67     if (action.code.length > this.sizeThreshold) {
   68       return BundleActionExecutor.executeMethod<O>(this.ensureLarge(), method, action);
   69     } else {
   70       return BundleActionExecutor.executeMethod<O>(this.ensureSmall(), method, action);
   71     }
   72   }
   73 
   74   async process(action: ProcessBundleOptions) {
   75     const cacheKeys = this.cache.generateCacheKeys(action);
   76     action.cacheKeys = cacheKeys;
   77 
   78     // Try to get cached data, if it fails fallback to processing
   79     try {
   80       const cachedResult = await this.cache.getCachedBundleResult(action);
   81       if (cachedResult) {
   82         return cachedResult;
   83       }
   84     } catch {}
   85 
   86     return this.executeAction<ProcessBundleResult>('process', action);
   87   }
   88 
   89   async *processAll(actions: Iterable<ProcessBundleOptions>) {
   90     const executions = new Map<Promise<ProcessBundleResult>, Promise<ProcessBundleResult>>();
   91     for (const action of actions) {
   92       const execution = this.process(action);
   93       executions.set(
   94         execution,
   95         execution.then(result => {
   96           executions.delete(execution);
   97 
   98           return result;
   99         }),
  100       );
  101     }
  102 
  103     while (executions.size > 0) {
  104       yield Promise.race(executions.values());
  105     }
  106   }
  107 
  108   stop() {
  109     if (this.largeWorker) {
  110       this.largeWorker.end();
  111     }
  112     if (this.smallWorker) {
  113       this.smallWorker.end();
  114     }
  115   }
  116 }