-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dgram: implement socket.bind({ fd })
dgram: Implement binding an existing `fd`. Allow pass a `fd` property to `socket.bind()` in dgram. src: Add `UDPWrap::Open` PR-URL: #21745 Fixes: #14961 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
- Loading branch information
Showing
10 changed files
with
442 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
'use strict'; | ||
const common = require('../common'); | ||
if (common.isWindows) | ||
common.skip('dgram clustering is currently not supported on Windows.'); | ||
|
||
const NUM_WORKERS = 4; | ||
const PACKETS_PER_WORKER = 10; | ||
|
||
const assert = require('assert'); | ||
const cluster = require('cluster'); | ||
const dgram = require('dgram'); | ||
const { UDP } = process.binding('udp_wrap'); | ||
|
||
if (cluster.isMaster) | ||
master(); | ||
else | ||
worker(); | ||
|
||
|
||
function master() { | ||
// Create a handle and use its fd. | ||
const rawHandle = new UDP(); | ||
const err = rawHandle.bind(common.localhostIPv4, 0, 0); | ||
assert(err >= 0, String(err)); | ||
assert.notStrictEqual(rawHandle.fd, -1); | ||
|
||
const fd = rawHandle.fd; | ||
|
||
let listening = 0; | ||
|
||
// Fork 4 workers. | ||
for (let i = 0; i < NUM_WORKERS; i++) | ||
cluster.fork(); | ||
|
||
// Wait until all workers are listening. | ||
cluster.on('listening', common.mustCall((worker, address) => { | ||
if (++listening < NUM_WORKERS) | ||
return; | ||
|
||
// Start sending messages. | ||
const buf = Buffer.from('hello world'); | ||
const socket = dgram.createSocket('udp4'); | ||
let sent = 0; | ||
doSend(); | ||
|
||
function doSend() { | ||
socket.send(buf, 0, buf.length, address.port, address.address, afterSend); | ||
} | ||
|
||
function afterSend() { | ||
sent++; | ||
if (sent < NUM_WORKERS * PACKETS_PER_WORKER) { | ||
doSend(); | ||
} else { | ||
socket.close(); | ||
} | ||
} | ||
}, NUM_WORKERS)); | ||
|
||
// Set up event handlers for every worker. Each worker sends a message when | ||
// it has received the expected number of packets. After that it disconnects. | ||
for (const key in cluster.workers) { | ||
if (cluster.workers.hasOwnProperty(key)) | ||
setupWorker(cluster.workers[key]); | ||
} | ||
|
||
function setupWorker(worker) { | ||
let received = 0; | ||
|
||
worker.send({ | ||
fd, | ||
}); | ||
|
||
worker.on('message', common.mustCall((msg) => { | ||
received = msg.received; | ||
worker.disconnect(); | ||
})); | ||
|
||
worker.on('exit', common.mustCall(() => { | ||
assert.strictEqual(received, PACKETS_PER_WORKER); | ||
})); | ||
} | ||
} | ||
|
||
|
||
function worker() { | ||
let received = 0; | ||
|
||
process.on('message', common.mustCall((data) => { | ||
const { fd } = data; | ||
// Create udp socket and start listening. | ||
const socket = dgram.createSocket('udp4'); | ||
|
||
socket.on('message', common.mustCall((data, info) => { | ||
received++; | ||
|
||
// Every 10 messages, notify the master. | ||
if (received === PACKETS_PER_WORKER) { | ||
process.send({ received }); | ||
socket.close(); | ||
} | ||
}, PACKETS_PER_WORKER)); | ||
|
||
socket.bind({ | ||
fd, | ||
}); | ||
})); | ||
} |
Oops, something went wrong.