| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent ff5bd04 commit 54bd4ab
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,6 +6,7 @@ const { | |||
| 6 | 6 | ObjectAssign, | |
| 7 | 7 | ReflectApply, | |
| 8 | 8 | SafeMap, | |
| 9 | + SafeSet, | ||
| 9 | 10 | } = primordials; | |
| 10 | 11 | ||
| 11 | 12 | const assert = require('internal/assert'); | |
@@ -73,14 +74,14 @@ cluster._getServer = function(obj, options, cb) { | |||
| 73 | 74 | options.fd, | |
| 74 | 75 | ], ':'); | |
| 75 | 76 | ||
| 76 | - let index = indexes.get(indexesKey); | ||
| 77 | + let indexSet = indexes.get(indexesKey); | ||
| 77 | 78 | ||
| 78 | - if (index === undefined) | ||
| 79 | - index = 0; | ||
| 80 | - else | ||
| 81 | - index++; | ||
| 82 | - | ||
| 83 | - indexes.set(indexesKey, index); | ||
| 79 | + if (indexSet === undefined) { | ||
| 80 | + indexSet = { nextIndex: 0, set: new SafeSet() }; | ||
| 81 | + indexes.set(indexesKey, indexSet); | ||
| 82 | + } | ||
| 83 | + const index = indexSet.nextIndex++; | ||
| 84 | + indexSet.set.add(index); | ||
| 84 | 85 | ||
| 85 | 86 | const message = { | |
| 86 | 87 | act: 'queryServer', | |
@@ -100,9 +101,9 @@ cluster._getServer = function(obj, options, cb) { | |||
| 100 | 101 | obj._setServerData(reply.data); | |
| 101 | 102 | ||
| 102 | 103 | if (handle) | |
| 103 | - shared(reply, handle, indexesKey, cb); // Shared listen socket. | ||
| 104 | + shared(reply, handle, indexesKey, index, cb); // Shared listen socket. | ||
| 104 | 105 | else | |
| 105 | - rr(reply, indexesKey, cb); // Round-robin. | ||
| 106 | + rr(reply, indexesKey, index, cb); // Round-robin. | ||
| 106 | 107 | }); | |
| 107 | 108 | ||
| 108 | 109 | obj.once('listening', () => { | |
@@ -114,8 +115,20 @@ cluster._getServer = function(obj, options, cb) { | |||
| 114 | 115 | }); | |
| 115 | 116 | }; | |
| 116 | 117 | ||
| 118 | + function removeIndexesKey(indexesKey, index) { | ||
| 119 | + const indexSet = indexes.get(indexesKey); | ||
| 120 | + if (!indexSet) { | ||
| 121 | + return; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + indexSet.set.delete(index); | ||
| 125 | + if (indexSet.set.size === 0) { | ||
| 126 | + indexes.delete(indexesKey); | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + | ||
| 117 | 130 | // Shared listen socket. | |
| 118 | - function shared(message, handle, indexesKey, cb) { | ||
| 131 | + function shared(message, handle, indexesKey, index, cb) { | ||
| 119 | 132 | const key = message.key; | |
| 120 | 133 | // Monkey-patch the close() method so we can keep track of when it's | |
| 121 | 134 | // closed. Avoids resource leaks when the handle is short-lived. | |
@@ -124,16 +137,16 @@ function shared(message, handle, indexesKey, cb) { | |||
| 124 | 137 | handle.close = function() { | |
| 125 | 138 | send({ act: 'close', key }); | |
| 126 | 139 | handles.delete(key); | |
| 127 | - indexes.delete(indexesKey); | ||
| 140 | + removeIndexesKey(indexesKey, index); | ||
| 128 | 141 | return ReflectApply(close, handle, arguments); | |
| 129 | 142 | }; | |
| 130 | 143 | assert(handles.has(key) === false); | |
| 131 | 144 | handles.set(key, handle); | |
| 132 | 145 | cb(message.errno, handle); | |
| 133 | 146 | } | |
| 134 | 147 | ||
| 135 | - // Round-robin. Master distributes handles across workers. | ||
| 136 | - function rr(message, indexesKey, cb) { | ||
| 148 | + // Round-robin. Primary distributes handles across workers. | ||
| 149 | + function rr(message, indexesKey, index, cb) { | ||
| 137 | 150 | if (message.errno) | |
| 138 | 151 | return cb(message.errno, null); | |
| 139 | 152 | ||
@@ -157,7 +170,7 @@ function rr(message, indexesKey, cb) { | |||
| 157 | 170 | ||
| 158 | 171 | send({ act: 'close', key }); | |
| 159 | 172 | handles.delete(key); | |
| 160 | - indexes.delete(indexesKey); | ||
| 173 | + removeIndexesKey(indexesKey, index); | ||
| 161 | 174 | key = undefined; | |
| 162 | 175 | } | |
| 163 | 176 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,40 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common'); | ||
| 3 | + const Countdown = require('../common/countdown'); | ||
| 4 | + if (common.isWindows) | ||
| 5 | + common.skip('dgram clustering is currently not supported on Windows.'); | ||
| 6 | + | ||
| 7 | + const cluster = require('cluster'); | ||
| 8 | + const dgram = require('dgram'); | ||
| 9 | + | ||
| 10 | + // Test an edge case when using `cluster` and `dgram.Socket.bind()` | ||
| 11 | + // the port of `0`. | ||
| 12 | + const kPort = 0; | ||
| 13 | + | ||
| 14 | + function child() { | ||
| 15 | + const kTime = 2; | ||
| 16 | + const countdown = new Countdown(kTime * 2, () => { | ||
| 17 | + process.exit(0); | ||
| 18 | + }); | ||
| 19 | + for (let i = 0; i < kTime; i += 1) { | ||
| 20 | + const socket = new dgram.Socket('udp4'); | ||
| 21 | + socket.bind(kPort, common.mustCall(() => { | ||
| 22 | + // `process.nextTick()` or `socket2.close()` would throw | ||
| 23 | + // ERR_SOCKET_DGRAM_NOT_RUNNING | ||
| 24 | + process.nextTick(() => { | ||
| 25 | + socket.close(countdown.dec()); | ||
| 26 | + const socket2 = new dgram.Socket('udp4'); | ||
| 27 | + socket2.bind(kPort, common.mustCall(() => { | ||
| 28 | + process.nextTick(() => { | ||
| 29 | + socket2.close(countdown.dec()); | ||
| 30 | + }); | ||
| 31 | + })); | ||
| 32 | + }); | ||
| 33 | + })); | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + if (cluster.isMaster) | ||
| 38 | + cluster.fork(__filename); | ||
| 39 | + else | ||
| 40 | + child(); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,31 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common'); | ||
| 3 | + const Countdown = require('../common/countdown'); | ||
| 4 | + const cluster = require('cluster'); | ||
| 5 | + const net = require('net'); | ||
| 6 | + | ||
| 7 | + // Test an edge case when using `cluster` and `net.Server.listen()` to | ||
| 8 | + // the port of `0`. | ||
| 9 | + const kPort = 0; | ||
| 10 | + | ||
| 11 | + function child() { | ||
| 12 | + const kTime = 2; | ||
| 13 | + const countdown = new Countdown(kTime * 2, () => { | ||
| 14 | + process.exit(0); | ||
| 15 | + }); | ||
| 16 | + for (let i = 0; i < kTime; i += 1) { | ||
| 17 | + const server = net.createServer(); | ||
| 18 | + server.listen(kPort, common.mustCall(() => { | ||
| 19 | + server.close(countdown.dec()); | ||
| 20 | + const server2 = net.createServer(); | ||
| 21 | + server2.listen(kPort, common.mustCall(() => { | ||
| 22 | + server2.close(countdown.dec()); | ||
| 23 | + })); | ||
| 24 | + })); | ||
| 25 | + } | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + if (cluster.isMaster) | ||
| 29 | + cluster.fork(__filename); | ||
| 30 | + else | ||
| 31 | + child(); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments