|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +const common = require('../common'); |
| 4 | +const assert = require('assert'); |
| 5 | +const cluster = require('cluster'); |
| 6 | +const http = require('http'); |
| 7 | +const net = require('net'); |
| 8 | + |
| 9 | +if (cluster.isMaster) { |
| 10 | + const numWorkers = 2; |
| 11 | + const pattern = [2, 1, 2, 2, 1, 2, 1, 1, 2]; |
| 12 | + let index = 0; |
| 13 | + let readyCount = 0; |
| 14 | + |
| 15 | + // The scheduler moves through pattern. Each request is scheduled to the |
| 16 | + // worker id specified in the current pattern index. |
| 17 | + const execute = (workers, socket) => { |
| 18 | + const id = pattern[index]; |
| 19 | + const worker = workers.get(id); |
| 20 | + |
| 21 | + if (id === 2) { |
| 22 | + assert.strictEqual(scheduler.exposeSocket, true); |
| 23 | + assert(socket instanceof net.Socket); |
| 24 | + } else { |
| 25 | + assert.strictEqual(scheduler.exposeSocket, false); |
| 26 | + assert.strictEqual(socket, undefined); |
| 27 | + } |
| 28 | + |
| 29 | + if (worker !== undefined) |
| 30 | + index++; |
| 31 | + |
| 32 | + return worker; |
| 33 | + }; |
| 34 | + |
| 35 | + const scheduler = { execute }; |
| 36 | + |
| 37 | + // Create a getter for exposeSocket. If the current item in the pattern is 2, |
| 38 | + // then expose the socket. Otherwise, hide it. |
| 39 | + Object.defineProperty(scheduler, 'exposeSocket', { |
| 40 | + get() { return pattern[index] === 2; } |
| 41 | + }); |
| 42 | + |
| 43 | + function onMessage(msg) { |
| 44 | + // Once both workers send a 'ready' signal, indicating that their servers |
| 45 | + // are listening, begin making HTTP requests. |
| 46 | + assert.strictEqual(msg.cmd, 'ready'); |
| 47 | + readyCount++; |
| 48 | + |
| 49 | + if (readyCount === numWorkers) |
| 50 | + makeRequest(0, msg.port); |
| 51 | + } |
| 52 | + |
| 53 | + function makeRequest(reqCount, port) { |
| 54 | + // Make one request for each element in pattern and then shut down the |
| 55 | + // workers. |
| 56 | + if (reqCount >= pattern.length) { |
| 57 | + for (const id in cluster.workers) |
| 58 | + cluster.workers[id].disconnect(); |
| 59 | + |
| 60 | + return; |
| 61 | + } |
| 62 | + |
| 63 | + http.get({ port }, (res) => { |
| 64 | + res.on('data', (data) => { |
| 65 | + assert.strictEqual(+data.toString(), pattern[reqCount]); |
| 66 | + reqCount++; |
| 67 | + makeRequest(reqCount, port); |
| 68 | + }); |
| 69 | + }); |
| 70 | + } |
| 71 | + |
| 72 | + cluster.setupMaster({ scheduler }); |
| 73 | + |
| 74 | + for (let i = 0; i < numWorkers; i++) |
| 75 | + cluster.fork().on('message', common.mustCall(onMessage)); |
| 76 | + |
| 77 | +} else { |
| 78 | + const server = http.createServer((req, res) => { |
| 79 | + res.end(cluster.worker.id + ''); |
| 80 | + }).listen(0, () => { |
| 81 | + process.send({ cmd: 'ready', port: server.address().port }); |
| 82 | + }); |
| 83 | +} |
0 commit comments