fixed problems with simultaneous pair creation
This commit is contained in:
parent
a1ac58ddfc
commit
fef369519c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
@ -1,15 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var server;
|
var PromiseA = require('bluebird');
|
||||||
var listening = false;
|
var promises = {};
|
||||||
var sock;
|
|
||||||
|
|
||||||
function createServer(cb, prefix) {
|
function createServer(prefix) {
|
||||||
var os = require('os');
|
var os = require('os');
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var path = require('path');
|
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())) {
|
if (/^win/.test(os.platform())) {
|
||||||
sock = path.join('\\\\?\\pipe', process.cwd(), sockname);
|
sock = path.join('\\\\?\\pipe', process.cwd(), sockname);
|
||||||
}
|
}
|
||||||
@ -17,52 +17,67 @@ function createServer(cb, prefix) {
|
|||||||
sock = path.join(os.tmpdir(), sockname);
|
sock = path.join(os.tmpdir(), sockname);
|
||||||
}
|
}
|
||||||
|
|
||||||
server = net.createServer();
|
var server = net.createServer({allowHalfOpen: true});
|
||||||
function onServerError(err) {
|
promises[prefix] = new PromiseA(function (resolve, reject) {
|
||||||
cb(err);
|
server.once('error', reject);
|
||||||
}
|
|
||||||
server.once('error', onServerError);
|
server.listen(sock, function () {
|
||||||
server.once('listening', function () {
|
server.removeListener('error', reject);
|
||||||
listening = true;
|
resolve({sock: sock, server: server});
|
||||||
server.removeListener('error', onServerError);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.on('close', function () {
|
||||||
|
delete promises[prefix];
|
||||||
|
});
|
||||||
|
|
||||||
|
return promises[prefix];
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.create = function create(cb, prefix) {
|
exports.create = function create(cb, prefix) {
|
||||||
|
prefix = prefix || 'node-socket-pair';
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var client = new net.Socket();
|
var client = new net.Socket({allowHalfOpen: true});
|
||||||
|
|
||||||
function createConnection() {
|
if (!promises[prefix]) {
|
||||||
function onClientError(err) {
|
createServer(prefix);
|
||||||
cb(err);
|
}
|
||||||
}
|
|
||||||
client.connect(sock, function () {
|
// We chain the promises to make sure that we never have multiple pending connections at
|
||||||
client.removeListener('error', onClientError);
|
// 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);
|
}, function (err) {
|
||||||
}
|
cb(err);
|
||||||
|
return PromiseA.reject(err);
|
||||||
// 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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!listening) {
|
|
||||||
server.listen(sock, createConnection);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
createConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.closeAll = function () {
|
exports.closeAll = function () {
|
||||||
if (server) {
|
Object.keys(promises).forEach(function (key) {
|
||||||
server.close();
|
promises[key].then(function (result) {
|
||||||
}
|
result.server.close();
|
||||||
|
}, function () {
|
||||||
|
delete promises[key];
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -23,5 +23,8 @@
|
|||||||
"writer"
|
"writer"
|
||||||
],
|
],
|
||||||
"author": "AJ ONeal <aj@daplie.com> (https://coolaj86.com)",
|
"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…
x
Reference in New Issue
Block a user