Files
meteor/packages/webapp/socket_file.js
2017-08-15 09:18:10 -04:00

62 lines
2.5 KiB
JavaScript

import { statSync, unlinkSync, existsSync } from 'fs';
// Since a new socket file will be created when the HTTP server
// starts up, if found remove the existing file.
//
// WARNING:
// This will remove the configured socket file without warning. If
// the configured socket file is already in use by another application,
// it will still be removed. Node does not provide a reliable way to
// differentiate between a socket file that is already in use by
// another application or a stale socket file that has been
// left over after a SIGKILL. Since we have no reliable way to
// differentiate between these two scenarios, the best course of
// action during startup is to remove any existing socket file. This
// is not the safest course of action as removing the existing socket
// file could impact an application using it, but this approach helps
// ensure the HTTP server can startup without manual
// intervention (e.g. asking for the verification and cleanup of socket
// files before allowing the HTTP server to be started).
//
// The above being said, as long as the socket file path is
// configured carefully when the application is deployed (and extra
// care is taken to make sure the configured path is unique and doesn't
// conflict with another socket file path), then there should not be
// any issues with this approach.
export const removeExistingSocketFile = (socketPath) => {
try {
if (statSync(socketPath).isSocket()) {
// Since a new socket file will be created, remove the existing
// file.
unlinkSync(socketPath);
} else {
throw new Error(
`An existing file was found at "${socketPath}" and it is not ` +
'a socket file. Please confirm PORT is pointing to valid and ' +
'un-used socket file path.'
);
}
} catch (error) {
// If there is no existing socket file to cleanup, great, we'll
// continue normally. If the caught exception represents any other
// issue, re-throw.
if (error.code !== 'ENOENT') {
throw error;
}
}
};
// Remove the socket file when done to avoid leaving behind a stale one.
// Note - a stale socket file is still left behind if the running node
// process is killed via signal 9 - SIGKILL.
export const registerSocketFileCleanup =
(socketPath, eventEmitter = process) => {
['exit', 'SIGINT', 'SIGHUP', 'SIGTERM'].forEach(signal => {
eventEmitter.on(signal, Meteor.bindEnvironment(() => {
if (existsSync(socketPath)) {
unlinkSync(socketPath);
}
}));
});
};