More careful socket cleanup
Summary: Instead of just deleting, we first check if it's already in use. The behaviour in case it *is* in use, is not great but mirrors what happens when the port is occupied. Reviewed By: aigoncharov Differential Revision: D35188965 fbshipit-source-id: 9bb5a7a9bacec6987ea72bbd084e40d5b30f9796
This commit is contained in:
committed by
Facebook GitHub Bot
parent
56e94394ca
commit
3d3e53c9e0
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
|
import net from 'net';
|
||||||
import express, {Express} from 'express';
|
import express, {Express} from 'express';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -67,6 +68,31 @@ async function startHTTPServer(
|
|||||||
return startProxyServer(config, app);
|
return startProxyServer(config, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkSocketInUse(path: string): Promise<boolean> {
|
||||||
|
if (!(await fs.pathExists(path))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, _reject) => {
|
||||||
|
const client = net
|
||||||
|
.createConnection(path, () => {
|
||||||
|
resolve(true);
|
||||||
|
client.destroy();
|
||||||
|
})
|
||||||
|
.on('error', (e) => {
|
||||||
|
if (e.message.includes('ECONNREFUSED')) {
|
||||||
|
resolve(false);
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`[conn] Socket ${path} is in use, but we don't know why.`,
|
||||||
|
e,
|
||||||
|
);
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
|
client.destroy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function startProxyServer(
|
async function startProxyServer(
|
||||||
config: Config,
|
config: Config,
|
||||||
app: Express,
|
app: Express,
|
||||||
@@ -85,8 +111,14 @@ async function startProxyServer(
|
|||||||
await fs.mkdirp(runtimeDir);
|
await fs.mkdirp(runtimeDir);
|
||||||
const socketPath = `${runtimeDir}/flipper-server-${userInfo().uid}.sock`;
|
const socketPath = `${runtimeDir}/flipper-server-${userInfo().uid}.sock`;
|
||||||
|
|
||||||
// TODO: More careful cleanup.
|
if (await checkSocketInUse(socketPath)) {
|
||||||
await fs.rm(socketPath, {force: true});
|
console.warn(
|
||||||
|
`Cannot start flipper-server because socket ${socketPath} is in use.`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.info(`Cleaning up stale socket ${socketPath}`);
|
||||||
|
await fs.rm(socketPath, {force: true});
|
||||||
|
}
|
||||||
|
|
||||||
const proxyServer = proxy.createProxyServer({
|
const proxyServer = proxy.createProxyServer({
|
||||||
target: {host: 'localhost', port: 0, socketPath},
|
target: {host: 'localhost', port: 0, socketPath},
|
||||||
@@ -96,6 +128,10 @@ async function startProxyServer(
|
|||||||
console.log('Starting socket server on ', socketPath);
|
console.log('Starting socket server on ', socketPath);
|
||||||
console.log(`Starting proxy server on http://localhost:${config.port}`);
|
console.log(`Starting proxy server on http://localhost:${config.port}`);
|
||||||
|
|
||||||
|
server.on('close', () => {
|
||||||
|
fs.remove(socketPath);
|
||||||
|
});
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
proxyServer.listen(config.port);
|
proxyServer.listen(config.port);
|
||||||
server.listen(socketPath, undefined, () => resolve({app, server}));
|
server.listen(socketPath, undefined, () => resolve({app, server}));
|
||||||
|
|||||||
Reference in New Issue
Block a user