verae-nats-cluster/scripts/udp-probe.mjs

54 lines
1.8 KiB
JavaScript
Executable file

#!/usr/bin/env node
/** UDP echo RTT. server: node udp-probe.mjs server [port]
* client: node udp-probe.mjs client <host> <count> [port] [size] */
import dgram from "node:dgram";
const mode = process.argv[2] || "server";
const port = Number(process.argv[mode === "server" ? 3 : 5] || 9999);
if (mode === "server") {
const s = dgram.createSocket("udp4");
s.on("message", (msg, rinfo) => s.send(msg, rinfo.port, rinfo.address));
s.bind(port, "0.0.0.0", () => console.log(JSON.stringify({ mode: "udp-server", port })));
} else {
const host = process.argv[3];
const count = Number(process.argv[4] || 1000);
const size = Number(process.argv[6] || 128);
const sock = dgram.createSocket("udp4");
const payload = Buffer.alloc(size, 7);
const samples = [];
let i = 0;
const sendOne = () => {
const t0 = process.hrtime.bigint();
const once = (msg) => {
sock.off("message", once);
samples.push(Number(process.hrtime.bigint() - t0) / 1000);
i += 1;
if (i >= count) {
samples.sort((a, b) => a - b);
const us = (n) => `${(n / 1000).toFixed(3)}ms`;
const pct = (p) => samples[Math.min(samples.length - 1, Math.floor((p / 100) * samples.length))];
const sum = samples.reduce((a, b) => a + b, 0);
console.log(
JSON.stringify({
mode: "udp-ping",
count: samples.length,
size,
host,
min: us(samples[0]),
avg: us(sum / samples.length),
p50: us(pct(50)),
p99: us(pct(99)),
max: us(samples[samples.length - 1]),
p50_us: Math.round(pct(50)),
p99_us: Math.round(pct(99)),
}),
);
sock.close();
} else sendOne();
};
sock.on("message", once);
sock.send(payload, port, host);
};
sendOne();
}