Right now before an unix socket is closed its file is also unlinked by libuv. This behavior seems to go against the current docs, which explicitly mention that the socket would persist until unlinked (seems to imply this doesn't happen automatically).
This behavior has already been discussed multiple times in past, and every time the result
of the conversation appears to have been that it is a bad idea.
Some problems this behavior causes:
- It makes restarts with little downtime very hard to implement, since normally
you would unlink the old socket in your new process immediately before listening to your new one.
However, if your old process calls server.close() afterwards, it will unlink your new socket. Bummer.
- A simple workaround would be not calling
server.close(), however now you lose the ability
to wait for old connection to die before exiting, and also the ability to not accept new connections before
you exit.
The best way to work around this problem I've found so far appears to be this safeListen:
// Edit: Replaced old workaround with a better one. Now we
// just rename the socket after creating it, so libuv can't know
// about the new path and thus can't unlink it.
const fs = require('fs');
function safeListen(httpServer, path, callback) {
callback = callback || function(error) {
if (error) {
httpServer.emit('error', error);
}
};
const tmpPath = path + '.' + process.pid + '.tmp';
httpServer.listen(tmpPath, (error) => {
if (error) {
return callback(error);
}
fs.rename(tmpPath, path, (error) => {
if (error) {
httpServer.close(() => {});
return callback(error);
}
callback(null, httpServer);
});
});
};
Right now before an unix socket is closed its file is also unlinked by libuv. This behavior seems to go against the current docs, which explicitly mention that the socket would persist until unlinked (seems to imply this doesn't happen automatically).
This behavior has already been discussed multiple times in past, and every time the result
of the conversation appears to have been that it is a bad idea.
Some problems this behavior causes:
you would unlink the old socket in your new process immediately before listening to your new one.
However, if your old process calls
server.close()afterwards, it will unlink your new socket. Bummer.server.close(), however now you lose the abilityto wait for old connection to die before exiting, and also the ability to not accept new connections before
you exit.
The best way to work around this problem I've found so far appears to be this
safeListen: