Files
react-native/packager/react-packager/src/SocketInterface/index.js
T
Kureev Alexey db3a00d58c Replace underscore by lodash
Summary:As far as we agreed to merge `rnpm` into react-native core, we need to align our dependencies to exclude duplications. One of the steps forward would be to use the same utilities library. According to the thread on fb, everybody is fine with replacing underscore by lodash (which we use internally for rnpm).

So, here we go!

cc mkonicek davidaurelio grabbou

**Test plan**
```
$ npm test
```
![image](https://cloud.githubusercontent.com/assets/2273613/13173972/ee34c922-d700-11e5-971b-68ff7322b6d6.png)

**Code formatting**

Changes are aligned with the current [style guide](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#style-guide).
Closes https://github.com/facebook/react-native/pull/6030

Differential Revision: D3016271

Pulled By: davidaurelio

fb-gh-sync-id: c4f6776a7de7470283d3ca5a8b56e423247f5e45
shipit-source-id: c4f6776a7de7470283d3ca5a8b56e423247f5e45
2016-03-09 03:09:44 -08:00

147 lines
3.8 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 crypto = require('crypto');
const debug = require('debug')('ReactNativePackager:SocketInterface');
const fs = require('fs');
const net = require('net');
const path = require('path');
const tmpdir = require('os').tmpdir();
const {spawn} = require('child_process');
const CREATE_SERVER_TIMEOUT = 5 * 60 * 1000;
const SocketInterface = {
getOrCreateSocketFor(options) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('md5');
Object.keys(options).sort().forEach(key => {
const value = options[key];
if (value) {
hash.update(
options[key] != null && typeof value === 'string'
? value
: JSON.stringify(value)
);
}
});
let sockPath = path.join(
tmpdir,
'react-packager-' + hash.digest('hex')
);
if (process.platform === 'win32'){
// on Windows, use a named pipe, convert sockPath into a valid pipe name
// based on https://gist.github.com/domenic/2790533
sockPath = sockPath.replace(/^\//, '')
sockPath = sockPath.replace(/\//g, '-')
sockPath = '\\\\.\\pipe\\' + sockPath
}
if (existsSync(sockPath)) {
var sock = net.connect(sockPath);
sock.on('connect', () => {
SocketClient.create(sockPath).then(
client => {
sock.end();
resolve(client);
},
error => {
sock.end();
reject(error);
}
);
});
sock.on('error', (e) => {
try {
debug('deleting socket for not responding', sockPath);
fs.unlinkSync(sockPath);
} catch (err) {
// Another client might have deleted it first.
}
createServer(resolve, reject, options, sockPath);
});
} else {
createServer(resolve, reject, options, sockPath);
}
});
},
listenOnServerMessages() {
return SocketServer.listenOnServerIPCMessages();
}
};
function createServer(resolve, reject, options, sockPath) {
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 = Object.assign({}, process.env);
env.DEBUG = 'ReactNativePackager: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 }
});
}
function existsSync(filename) {
try {
fs.accessSync(filename);
return true;
} catch(ex) {
return false;
}
}
module.exports = SocketInterface;