fixed problems with simultaneous pair creation
This commit is contained in:
parent
a1ac58ddfc
commit
fef369519c
|
@ -0,0 +1 @@
|
|||
node_modules/
|
|
@ -1,15 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
var server;
|
||||
var listening = false;
|
||||
var sock;
|
||||
var PromiseA = require('bluebird');
|
||||
var promises = {};
|
||||
|
||||
function createServer(cb, prefix) {
|
||||
function createServer(prefix) {
|
||||
var os = require('os');
|
||||
var net = require('net');
|
||||
var path = require('path');
|
||||
var sockname = (prefix || 'node-socket-pair') + '.' + require('crypto').randomBytes(16).toString('hex') + '.sock';
|
||||
var sockname = prefix + '.' + require('crypto').randomBytes(16).toString('hex') + '.sock';
|
||||
|
||||
var sock;
|
||||
if (/^win/.test(os.platform())) {
|
||||
sock = path.join('\\\\?\\pipe', process.cwd(), sockname);
|
||||
}
|
||||
|
@ -17,52 +17,67 @@ function createServer(cb, prefix) {
|
|||
sock = path.join(os.tmpdir(), sockname);
|
||||
}
|
||||
|
||||
server = net.createServer();
|
||||
function onServerError(err) {
|
||||
cb(err);
|
||||
}
|
||||
server.once('error', onServerError);
|
||||
server.once('listening', function () {
|
||||
listening = true;
|
||||
server.removeListener('error', onServerError);
|
||||
var server = net.createServer({allowHalfOpen: true});
|
||||
promises[prefix] = new PromiseA(function (resolve, reject) {
|
||||
server.once('error', reject);
|
||||
|
||||
server.listen(sock, function () {
|
||||
server.removeListener('error', reject);
|
||||
resolve({sock: sock, server: server});
|
||||
});
|
||||
});
|
||||
|
||||
server.on('close', function () {
|
||||
delete promises[prefix];
|
||||
});
|
||||
|
||||
return promises[prefix];
|
||||
}
|
||||
|
||||
exports.create = function create(cb, prefix) {
|
||||
prefix = prefix || 'node-socket-pair';
|
||||
var net = require('net');
|
||||
var client = new net.Socket();
|
||||
var client = new net.Socket({allowHalfOpen: true});
|
||||
|
||||
function createConnection() {
|
||||
function onClientError(err) {
|
||||
cb(err);
|
||||
}
|
||||
client.connect(sock, function () {
|
||||
client.removeListener('error', onClientError);
|
||||
if (!promises[prefix]) {
|
||||
createServer(prefix);
|
||||
}
|
||||
|
||||
// We chain the promises to make sure that we never have multiple pending connections at
|
||||
// the same time to make sure the pairs are always matched correctly. Otherwise two different
|
||||
// `onConn` listeners might end up with the same connection.
|
||||
promises[prefix] = promises[prefix].then(function (result) {
|
||||
return new PromiseA(function (resolve) {
|
||||
function onConn(conn) {
|
||||
cb(null, conn);
|
||||
resolve(result);
|
||||
}
|
||||
result.server.once('connection', onConn);
|
||||
|
||||
function onErr(err) {
|
||||
result.server.removeListener('connection', onConn);
|
||||
cb(err);
|
||||
resolve(result);
|
||||
}
|
||||
client.once('error', onErr);
|
||||
client.connect(result.sock, function () {
|
||||
client.removeListener('error', onErr);
|
||||
});
|
||||
});
|
||||
client.once('error', onClientError);
|
||||
}
|
||||
|
||||
// This server listens on a Unix socket or Windows pipe at 'sock'
|
||||
if (!server) {
|
||||
createServer(cb, prefix);
|
||||
}
|
||||
|
||||
server.once('connection', function onEach(connection) {
|
||||
cb(null, connection);
|
||||
}, function (err) {
|
||||
cb(err);
|
||||
return PromiseA.reject(err);
|
||||
});
|
||||
|
||||
if (!listening) {
|
||||
server.listen(sock, createConnection);
|
||||
}
|
||||
else {
|
||||
createConnection();
|
||||
}
|
||||
|
||||
return client;
|
||||
};
|
||||
|
||||
exports.closeAll = function () {
|
||||
if (server) {
|
||||
server.close();
|
||||
}
|
||||
Object.keys(promises).forEach(function (key) {
|
||||
promises[key].then(function (result) {
|
||||
result.server.close();
|
||||
}, function () {
|
||||
delete promises[key];
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -23,5 +23,8 @@
|
|||
"writer"
|
||||
],
|
||||
"author": "AJ ONeal <aj@daplie.com> (https://coolaj86.com)",
|
||||
"license": "MIT OR Apache-2.0"
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.5.0"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue