Files
react-native/packager/react-packager/src/SocketInterface/SocketClient.js
Amjad Masad bceab6c1c2 [react-packager] Allow a longer startup time before the server dies
Summary:
1. When the server starts up, it only gives itself 30 second to live before receiving any connections/jobs
2. There is a startup cost with starting the server and handshaking
3. The server dies before the client has a chance to connect to it

Solution:
1. While the server should die pretty fast after it's done it's work, we should have a longer timeout for starting it
2. I also added accompanying server logs with client connection errors
2015-09-07 10:31:49 -08:00

118 lines
2.9 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 Bundle = require('../Bundler/Bundle');
const Promise = require('promise');
const bser = require('bser');
const debug = require('debug')('ReactPackager:SocketClient');
const fs = require('fs');
const net = require('net');
const path = require('path');
const tmpdir = require('os').tmpdir();
const LOG_PATH = path.join(tmpdir, 'react-packager.log');
class SocketClient {
static create(sockPath) {
return new SocketClient(sockPath).onReady();
}
constructor(sockPath) {
debug('connecting to', sockPath);
this._sock = net.connect(sockPath);
this._ready = new Promise((resolve, reject) => {
this._sock.on('connect', () => resolve(this));
this._sock.on('error', (e) => {
e.message = `Error connecting to server on ${sockPath} ` +
`with error: ${e.message}`;
if (fs.existsSync(LOG_PATH)) {
e.message += '\nServer logs:\n' + fs.readFileSync(LOG_PATH, 'utf8');
}
reject(e);
});
});
this._resolvers = Object.create(null);
const bunser = new bser.BunserBuf();
this._sock.on('data', (buf) => bunser.append(buf));
bunser.on('value', (message) => this._handleMessage(message));
}
onReady() {
return this._ready;
}
getDependencies(main) {
return this._send({
type: 'getDependencies',
data: main,
});
}
buildBundle(options) {
return this._send({
type: 'buildBundle',
data: options,
}).then(json => Bundle.fromJSON(json));
}
_send(message) {
message.id = uid();
this._sock.write(bser.dumpToBuffer(message));
return new Promise((resolve, reject) => {
this._resolvers[message.id] = {resolve, reject};
});
}
_handleMessage(message) {
if (!(message && message.id && message.type)) {
throw new Error(
'Malformed message from server ' + JSON.stringify(message)
);
}
debug('got message with type', message.type);
const resolver = this._resolvers[message.id];
if (!resolver) {
throw new Error(
'Unrecognized message id (' + message.id + ') ' +
'message already resolved or never existed.'
);
}
delete this._resolvers[message.id];
if (message.type === 'error') {
resolver.reject(new Error(
message.data + '\n' + 'See logs ' + LOG_PATH
));
} else {
resolver.resolve(message.data);
}
}
close() {
debug('closing connection');
this._sock.end();
}
}
module.exports = SocketClient;
function uid(len) {
len = len || 7;
return Math.random().toString(35).substr(2, len);
}