Skip to content

Commit 20d3378

Browse files
santigimenoMyles Borins
authored andcommitted
cluster: reset handle index on close
It allows reopening a server after it has been closed. Fixes: #6693 PR-URL: #6981 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ron Korving <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 09349a8 commit 20d3378

File tree

3 files changed

+88
-12
lines changed

3 files changed

+88
-12
lines changed

‎lib/cluster.js‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -555,18 +555,18 @@ function workerInit(){
555555

556556
// obj is a net#Server or a dgram#Socket object.
557557
cluster._getServer=function(obj,options,cb){
558-
constkey=[options.address,
559-
options.port,
560-
options.addressType,
561-
options.fd].join(':');
562-
if(indexes[key]===undefined)
563-
indexes[key]=0;
558+
constindexesKey=[options.address,
559+
options.port,
560+
options.addressType,
561+
options.fd].join(':');
562+
if(indexes[indexesKey]===undefined)
563+
indexes[indexesKey]=0;
564564
else
565-
indexes[key]++;
565+
indexes[indexesKey]++;
566566

567567
constmessage=util._extend({
568568
act: 'queryServer',
569-
index: indexes[key],
569+
index: indexes[indexesKey],
570570
data: null
571571
},options);
572572

@@ -576,9 +576,9 @@ function workerInit(){
576576
if(obj._setServerData)obj._setServerData(reply.data);
577577

578578
if(handle)
579-
shared(reply,handle,cb);// Shared listen socket.
579+
shared(reply,handle,indexesKey,cb);// Shared listen socket.
580580
else
581-
rr(reply,cb);// Round-robin.
581+
rr(reply,indexesKey,cb);// Round-robin.
582582
});
583583
obj.once('listening',function(){
584584
cluster.worker.state='listening';
@@ -590,14 +590,15 @@ function workerInit(){
590590
};
591591

592592
// Shared listen socket.
593-
functionshared(message,handle,cb){
593+
functionshared(message,handle,indexesKey,cb){
594594
varkey=message.key;
595595
// Monkey-patch the close() method so we can keep track of when it's
596596
// closed. Avoids resource leaks when the handle is short-lived.
597597
varclose=handle.close;
598598
handle.close=function(){
599599
send({act: 'close',key: key});
600600
deletehandles[key];
601+
deleteindexes[indexesKey];
601602
returnclose.apply(this,arguments);
602603
};
603604
assert(handles[key]===undefined);
@@ -606,7 +607,7 @@ function workerInit(){
606607
}
607608

608609
// Round-robin. Master distributes handles across workers.
609-
functionrr(message,cb){
610+
functionrr(message,indexesKey,cb){
610611
if(message.errno)
611612
returncb(message.errno,null);
612613

@@ -627,6 +628,7 @@ function workerInit(){
627628
if(key===undefined)return;
628629
send({act: 'close',key: key});
629630
deletehandles[key];
631+
deleteindexes[indexesKey];
630632
key=undefined;
631633
}
632634

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
constassert=require('assert');
4+
constcluster=require('cluster');
5+
6+
cluster.schedulingPolicy=cluster.SCHED_NONE;
7+
8+
if(cluster.isMaster){
9+
constworker1=cluster.fork();
10+
worker1.on('listening',common.mustCall(()=>{
11+
constworker2=cluster.fork();
12+
worker2.on('exit',(code,signal)=>{
13+
assert.strictEqual(code,0,'worker2 did not exit normally');
14+
assert.strictEqual(signal,null,'worker2 did not exit normally');
15+
worker1.disconnect();
16+
});
17+
}));
18+
19+
worker1.on('exit',common.mustCall((code,signal)=>{
20+
assert.strictEqual(code,0,'worker1 did not exit normally');
21+
assert.strictEqual(signal,null,'worker1 did not exit normally');
22+
}));
23+
}else{
24+
constnet=require('net');
25+
constserver=net.createServer();
26+
server.listen(common.PORT,common.mustCall(()=>{
27+
if(cluster.worker.id===2){
28+
server.close(()=>{
29+
server.listen(common.PORT,common.mustCall(()=>{
30+
server.close(()=>{
31+
process.disconnect();
32+
});
33+
}));
34+
});
35+
}
36+
}));
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
constassert=require('assert');
4+
constcluster=require('cluster');
5+
6+
cluster.schedulingPolicy=cluster.SCHED_RR;
7+
8+
if(cluster.isMaster){
9+
constworker1=cluster.fork();
10+
worker1.on('listening',common.mustCall(()=>{
11+
constworker2=cluster.fork();
12+
worker2.on('exit',(code,signal)=>{
13+
assert.strictEqual(code,0,'worker2 did not exit normally');
14+
assert.strictEqual(signal,null,'worker2 did not exit normally');
15+
worker1.disconnect();
16+
});
17+
}));
18+
19+
worker1.on('exit',common.mustCall((code,signal)=>{
20+
assert.strictEqual(code,0,'worker1 did not exit normally');
21+
assert.strictEqual(signal,null,'worker1 did not exit normally');
22+
}));
23+
}else{
24+
constnet=require('net');
25+
constserver=net.createServer();
26+
server.listen(common.PORT,common.mustCall(()=>{
27+
if(cluster.worker.id===2){
28+
server.close(()=>{
29+
server.listen(common.PORT,common.mustCall(()=>{
30+
server.close(()=>{
31+
process.disconnect();
32+
});
33+
}));
34+
});
35+
}
36+
}));
37+
}

0 commit comments

Comments
(0)