From 54f91bd951da51bfe908130d71e3469d65d01f1d Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Thu, 3 Sep 2015 14:42:47 -0700 Subject: [PATCH] [react-packager] Socket Server should not die while there active connections Summary: Saw an issue with a build because of an ENONT error: https://fb.facebook.com/groups/716936458354972/permalink/923628747685741/ My hypothesis: 1. We issue a ping to the socket (in SocketInterface/index.js) a decides if the available socket is alive 2. We see that it's alive but by the time we actually connect to it the server would've died Solution: 1. The server shouldn't die as long as there are clients connected to it (currently it only stay alive as long as there are jobs) 2. The "ping" should only disconnect once the client is connected 3. Finally, have a better error message than ENOENT --- .../src/SocketInterface/SocketClient.js | 6 +++++- .../src/SocketInterface/SocketServer.js | 7 ++++++- packager/react-packager/src/SocketInterface/index.js | 12 ++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packager/react-packager/src/SocketInterface/SocketClient.js b/packager/react-packager/src/SocketInterface/SocketClient.js index e20e5b896..6ccfd4819 100644 --- a/packager/react-packager/src/SocketInterface/SocketClient.js +++ b/packager/react-packager/src/SocketInterface/SocketClient.js @@ -29,7 +29,11 @@ class SocketClient { this._sock = net.connect(sockPath); this._ready = new Promise((resolve, reject) => { this._sock.on('connect', () => resolve(this)); - this._sock.on('error', (e) => reject(e)); + this._sock.on('error', (e) => { + e.message = `Error connecting to server on ${sockPath}` + + `with error: ${e.message}`; + reject(e); + }); }); this._resolvers = Object.create(null); diff --git a/packager/react-packager/src/SocketInterface/SocketServer.js b/packager/react-packager/src/SocketInterface/SocketServer.js index b292b2bfa..abdc094b7 100644 --- a/packager/react-packager/src/SocketInterface/SocketServer.js +++ b/packager/react-packager/src/SocketInterface/SocketServer.js @@ -35,6 +35,8 @@ class SocketServer { process.on('exit', () => fs.unlinkSync(sockPath)); }); }); + + this._numConnections = 0; this._server.on('connection', (sock) => this._handleConnection(sock)); // Disable the file watcher. @@ -50,10 +52,13 @@ class SocketServer { _handleConnection(sock) { debug('connection to server', process.pid); + this._numConnections++; + sock.on('close', () => this._numConnections--); const bunser = new bser.BunserBuf(); sock.on('data', (buf) => bunser.append(buf)); bunser.on('value', (m) => this._handleMessage(sock, m)); + bunser.on('error', (e) => console.error(e)); } _handleMessage(sock, m) { @@ -116,7 +121,7 @@ class SocketServer { _dieEventually() { clearTimeout(this._deathTimer); this._deathTimer = setTimeout(() => { - if (this._jobs <= 0) { + if (this._jobs <= 0 && this._numConnections <= 0) { debug('server dying', process.pid); process.exit(); } diff --git a/packager/react-packager/src/SocketInterface/index.js b/packager/react-packager/src/SocketInterface/index.js index 19b39bf09..f3dce21a0 100644 --- a/packager/react-packager/src/SocketInterface/index.js +++ b/packager/react-packager/src/SocketInterface/index.js @@ -42,8 +42,16 @@ const SocketInterface = { if (fs.existsSync(sockPath)) { var sock = net.connect(sockPath); sock.on('connect', () => { - sock.end(); - resolve(SocketClient.create(sockPath)); + SocketClient.create(sockPath).then( + client => { + sock.end(); + resolve(client); + }, + error => { + sock.end(); + reject(error); + } + ); }); sock.on('error', (e) => { try {