-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cluster: allow shared reused dgram sockets #2548
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,7 +57,7 @@ Worker.prototype.isConnected = function isConnected() { | |
|
||
// Master/worker specific methods are defined in the *Init() functions. | ||
|
||
function SharedHandle(key, address, port, addressType, backlog, fd) { | ||
function SharedHandle(key, address, port, addressType, backlog, fd, flags) { | ||
this.key = key; | ||
this.workers = []; | ||
this.handle = null; | ||
|
@@ -66,7 +66,7 @@ function SharedHandle(key, address, port, addressType, backlog, fd) { | |
// FIXME(bnoordhuis) Polymorphic return type for lack of a better solution. | ||
var rval; | ||
if (addressType === 'udp4' || addressType === 'udp6') | ||
rval = dgram._createSocketHandle(address, port, addressType, fd); | ||
rval = dgram._createSocketHandle(address, port, addressType, fd, flags); | ||
else | ||
rval = net._createServerHandle(address, port, addressType, fd); | ||
|
||
|
@@ -438,7 +438,8 @@ function masterInit() { | |
var args = [message.address, | ||
message.port, | ||
message.addressType, | ||
message.fd]; | ||
message.fd, | ||
message.index]; | ||
var key = args.join(':'); | ||
var handle = handles[key]; | ||
if (handle === undefined) { | ||
|
@@ -456,7 +457,8 @@ function masterInit() { | |
message.port, | ||
message.addressType, | ||
message.backlog, | ||
message.fd); | ||
message.fd, | ||
message.flags); | ||
} | ||
if (!handle.data) handle.data = message.data; | ||
|
||
|
@@ -485,7 +487,7 @@ function masterInit() { | |
cluster.emit('listening', worker, info); | ||
} | ||
|
||
// Round-robin only. Server in worker is closing, remove from list. | ||
// Server in worker is closing, remove from list. | ||
function close(worker, message) { | ||
var key = message.key; | ||
var handle = handles[key]; | ||
|
@@ -500,6 +502,7 @@ function masterInit() { | |
|
||
function workerInit() { | ||
var handles = {}; | ||
var indexes = {}; | ||
|
||
// Called from src/node.js | ||
cluster._setupWorker = function() { | ||
|
@@ -528,15 +531,22 @@ function workerInit() { | |
}; | ||
|
||
// obj is a net#Server or a dgram#Socket object. | ||
cluster._getServer = function(obj, address, port, addressType, fd, cb) { | ||
var message = { | ||
addressType: addressType, | ||
address: address, | ||
port: port, | ||
cluster._getServer = function(obj, options, cb) { | ||
const key = [ options.address, | ||
options.port, | ||
options.addressType, | ||
options.fd ].join(':'); | ||
if (indexes[key] === undefined) | ||
indexes[key] = 0; | ||
else | ||
indexes[key]++; | ||
|
||
const message = util._extend({ | ||
act: 'queryServer', | ||
fd: fd, | ||
index: indexes[key], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can avoid the extra lookup if you write the initial one like this: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No extra lookup, v8 is using GVN! :) Also, I'm kind of against |
||
data: null | ||
}; | ||
}, options); | ||
|
||
// Set custom data on handle (i.e. tls tickets key) | ||
if (obj._getServerData) message.data = obj._getServerData(); | ||
send(message, function(reply, handle) { | ||
|
@@ -549,9 +559,9 @@ function workerInit() { | |
}); | ||
obj.once('listening', function() { | ||
cluster.worker.state = 'listening'; | ||
var address = obj.address(); | ||
const address = obj.address(); | ||
message.act = 'listening'; | ||
message.port = address && address.port || port; | ||
message.port = address && address.port || options.port; | ||
send(message); | ||
}); | ||
}; | ||
|
@@ -563,6 +573,7 @@ function workerInit() { | |
// closed. Avoids resource leaks when the handle is short-lived. | ||
var close = handle.close; | ||
handle.close = function() { | ||
send({ act: 'close', key: key }); | ||
delete handles[key]; | ||
return close.apply(this, arguments); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
'use strict'; | ||
const common = require('../common'); | ||
const assert = require('assert'); | ||
const cluster = require('cluster'); | ||
const dgram = require('dgram'); | ||
|
||
if (cluster.isMaster) { | ||
cluster.fork().on('exit', function(code) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
assert.equal(code, 0); | ||
}); | ||
return; | ||
} | ||
|
||
const sockets = []; | ||
function next() { | ||
sockets.push(this); | ||
if (sockets.length !== 2) | ||
return; | ||
|
||
// Work around health check issue | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment could go into a little more detail. |
||
process.nextTick(function() { | ||
for (var i = 0; i < sockets.length; i++) | ||
sockets[i].close(close); | ||
}); | ||
} | ||
|
||
var waiting = 2; | ||
function close() { | ||
if (--waiting === 0) | ||
cluster.worker.disconnect(); | ||
} | ||
|
||
for (var i = 0; i < 2; i++) | ||
dgram.createSocket({ type: 'udp4', reuseAddr: true }).bind(common.PORT, next); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const key = ...
?