Files
react-native/packager/react-packager/src/SocketInterface/index.js
2015-08-25 17:36:08 -08:00

104 lines
2.7 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
const Promise = require('promise');
const SocketClient = require('./SocketClient');
const SocketServer = require('./SocketServer');
const _ = require('underscore');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const tmpdir = require('os').tmpdir();
const {spawn} = require('child_process');
const CREATE_SERVER_TIMEOUT = 30000;
const SocketInterface = {
getOrCreateSocketFor(options) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('md5');
Object.keys(options).sort().forEach(key => {
if (options[key] && typeof options[key] !== 'string') {
hash.update(JSON.stringify(options[key]));
} else {
hash.update(options[key]);
}
});
const sockPath = path.join(
tmpdir,
'react-packager-' + hash.digest('hex')
);
if (fs.existsSync(sockPath)) {
resolve(SocketClient.create(sockPath));
return;
}
const logPath = path.join(tmpdir, 'react-packager.log');
const timeout = setTimeout(
() => reject(
new Error(
'Took too long to start server. Server logs: \n' +
fs.readFileSync(logPath, 'utf8')
)
),
CREATE_SERVER_TIMEOUT,
);
const log = fs.openSync(logPath, 'a');
// Enable server debugging by default since it's going to a log file.
const env = _.clone(process.env);
env.DEBUG = 'ReactPackager:SocketServer';
// We have to go through the main entry point to make sure
// we go through the babel require hook.
const child = spawn(
process.execPath,
[path.join(__dirname, '..', '..', 'index.js')],
{
detached: true,
env: env,
stdio: ['ipc', log, log]
}
);
child.unref();
child.on('message', m => {
if (m && m.type && m.type === 'createdServer') {
clearTimeout(timeout);
child.disconnect();
resolve(SocketClient.create(sockPath));
}
});
if (options.blacklistRE) {
options.blacklistRE = { source: options.blacklistRE.source };
}
child.send({
type: 'createSocketServer',
data: { sockPath, options }
});
});
},
listenOnServerMessages() {
return SocketServer.listenOnServerIPCMessages();
}
};
module.exports = SocketInterface;