[react-packager] Set a lifetime on workers to avoid memory leaks

This commit is contained in:
Amjad Masad 2015-08-12 19:04:54 -07:00
Родитель 08d1bc8c9f
Коммит 7750db05e6
1 изменённых файлов: 48 добавлений и 39 удалений

Просмотреть файл

@ -8,19 +8,16 @@
*/ */
'use strict'; 'use strict';
var fs = require('fs'); const ModuleTransport = require('../lib/ModuleTransport');
var Promise = require('promise'); const Promise = require('promise');
var workerFarm = require('worker-farm'); const declareOpts = require('../lib/declareOpts');
var declareOpts = require('../lib/declareOpts'); const fs = require('fs');
var util = require('util'); const util = require('util');
var ModuleTransport = require('../lib/ModuleTransport'); const workerFarm = require('worker-farm');
var readFile = Promise.denodeify(fs.readFile); const readFile = Promise.denodeify(fs.readFile);
module.exports = Transformer; const validateOpts = declareOpts({
Transformer.TransformError = TransformError;
var validateOpts = declareOpts({
projectRoots: { projectRoots: {
type: 'array', type: 'array',
required: true, required: true,
@ -42,30 +39,37 @@ var validateOpts = declareOpts({
}, },
}); });
function Transformer(options) { // Avoid memory leaks caused in workers. This number seems to be a good enough number
var opts = validateOpts(options); // to avoid any memory leak while not slowing down initial builds.
// TODO(amasad): Once we get bundle splitting, we can drive this down a bit more.
const MAX_CALLS_PER_WORKER = 600;
class Transformer {
constructor(options) {
const opts = validateOpts(options);
this._cache = opts.cache; this._cache = opts.cache;
if (options.transformModulePath != null) { if (opts.transformModulePath != null) {
this._workers = workerFarm( this._workers = workerFarm({
{autoStart: true, maxConcurrentCallsPerWorker: 1}, autoStart: true,
options.transformModulePath maxConcurrentCallsPerWorker: 1,
); maxCallsPerWorker: MAX_CALLS_PER_WORKER,
}, opts.transformModulePath);
this._transform = Promise.denodeify(this._workers); this._transform = Promise.denodeify(this._workers);
} }
} }
Transformer.prototype.kill = function() { kill() {
this._workers && workerFarm.end(this._workers); this._workers && workerFarm.end(this._workers);
}; }
Transformer.prototype.invalidateFile = function(filePath) { invalidateFile(filePath) {
this._cache.invalidate(filePath); this._cache.invalidate(filePath);
}; }
Transformer.prototype.loadFileAndTransform = function(filePath) { loadFileAndTransform(filePath) {
if (this._transform == null) { if (this._transform == null) {
return Promise.reject(new Error('No transfrom module')); return Promise.reject(new Error('No transfrom module'));
} }
@ -103,7 +107,12 @@ Transformer.prototype.loadFileAndTransform = function(filePath) {
throw formatError(err, filePath); throw formatError(err, filePath);
}); });
}); });
}; }
}
module.exports = Transformer;
Transformer.TransformError = TransformError;
function TransformError() { function TransformError() {
Error.captureStackTrace && Error.captureStackTrace(this, TransformError); Error.captureStackTrace && Error.captureStackTrace(this, TransformError);