11cb0ef41Sopenharmony_ci// Test UDP send throughput with the multi buffer API against Buffer.concat
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ciconst common = require('../common.js');
51cb0ef41Sopenharmony_ciconst dgram = require('dgram');
61cb0ef41Sopenharmony_ciconst PORT = common.PORT;
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci// `num` is the number of send requests to queue up each time.
91cb0ef41Sopenharmony_ci// Keep it reasonably high (>10) otherwise you're benchmarking the speed of
101cb0ef41Sopenharmony_ci// event loop cycles more than anything else.
111cb0ef41Sopenharmony_ciconst bench = common.createBenchmark(main, {
121cb0ef41Sopenharmony_ci  len: [64, 256, 512, 1024],
131cb0ef41Sopenharmony_ci  num: [100],
141cb0ef41Sopenharmony_ci  chunks: [1, 2, 4, 8],
151cb0ef41Sopenharmony_ci  type: ['concat', 'multi'],
161cb0ef41Sopenharmony_ci  dur: [5],
171cb0ef41Sopenharmony_ci});
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cifunction main({ dur, len, num, type, chunks }) {
201cb0ef41Sopenharmony_ci  const chunk = [];
211cb0ef41Sopenharmony_ci  for (let i = 0; i < chunks; i++) {
221cb0ef41Sopenharmony_ci    chunk.push(Buffer.allocUnsafe(Math.round(len / chunks)));
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci  // Server
261cb0ef41Sopenharmony_ci  let sent = 0;
271cb0ef41Sopenharmony_ci  const socket = dgram.createSocket('udp4');
281cb0ef41Sopenharmony_ci  const onsend = type === 'concat' ? onsendConcat : onsendMulti;
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  function onsendConcat() {
311cb0ef41Sopenharmony_ci    if (sent++ % num === 0) {
321cb0ef41Sopenharmony_ci      // The setImmediate() is necessary to have event loop progress on OSes
331cb0ef41Sopenharmony_ci      // that only perform synchronous I/O on nonblocking UDP sockets.
341cb0ef41Sopenharmony_ci      setImmediate(() => {
351cb0ef41Sopenharmony_ci        for (let i = 0; i < num; i++) {
361cb0ef41Sopenharmony_ci          socket.send(Buffer.concat(chunk), PORT, '127.0.0.1', onsend);
371cb0ef41Sopenharmony_ci        }
381cb0ef41Sopenharmony_ci      });
391cb0ef41Sopenharmony_ci    }
401cb0ef41Sopenharmony_ci  }
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  function onsendMulti() {
431cb0ef41Sopenharmony_ci    if (sent++ % num === 0) {
441cb0ef41Sopenharmony_ci      // The setImmediate() is necessary to have event loop progress on OSes
451cb0ef41Sopenharmony_ci      // that only perform synchronous I/O on nonblocking UDP sockets.
461cb0ef41Sopenharmony_ci      setImmediate(() => {
471cb0ef41Sopenharmony_ci        for (let i = 0; i < num; i++) {
481cb0ef41Sopenharmony_ci          socket.send(chunk, PORT, '127.0.0.1', onsend);
491cb0ef41Sopenharmony_ci        }
501cb0ef41Sopenharmony_ci      });
511cb0ef41Sopenharmony_ci    }
521cb0ef41Sopenharmony_ci  }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  socket.on('listening', () => {
551cb0ef41Sopenharmony_ci    bench.start();
561cb0ef41Sopenharmony_ci    onsend();
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    setTimeout(() => {
591cb0ef41Sopenharmony_ci      const bytes = sent * len;
601cb0ef41Sopenharmony_ci      const gbits = (bytes * 8) / (1024 * 1024 * 1024);
611cb0ef41Sopenharmony_ci      bench.end(gbits);
621cb0ef41Sopenharmony_ci      process.exit(0);
631cb0ef41Sopenharmony_ci    }, dur * 1000);
641cb0ef41Sopenharmony_ci  });
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  socket.bind(PORT);
671cb0ef41Sopenharmony_ci}
68