11cb0ef41Sopenharmony_ci// Test the speed of .pipe() with sockets 21cb0ef41Sopenharmony_ci'use strict'; 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciconst common = require('../common.js'); 51cb0ef41Sopenharmony_ciconst PORT = common.PORT; 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst bench = common.createBenchmark(main, { 81cb0ef41Sopenharmony_ci sendchunklen: [256, 32 * 1024, 128 * 1024, 16 * 1024 * 1024], 91cb0ef41Sopenharmony_ci type: ['utf', 'asc', 'buf'], 101cb0ef41Sopenharmony_ci recvbuflen: [0, 64 * 1024, 1024 * 1024], 111cb0ef41Sopenharmony_ci recvbufgenfn: ['true', 'false'], 121cb0ef41Sopenharmony_ci dur: [5], 131cb0ef41Sopenharmony_ci}, { 141cb0ef41Sopenharmony_ci test: { sendchunklen: 256 }, 151cb0ef41Sopenharmony_ci}); 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_cilet chunk; 181cb0ef41Sopenharmony_cilet encoding; 191cb0ef41Sopenharmony_cilet recvbuf; 201cb0ef41Sopenharmony_cilet received = 0; 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_cifunction main({ dur, sendchunklen, type, recvbuflen, recvbufgenfn }) { 231cb0ef41Sopenharmony_ci if (isFinite(recvbuflen) && recvbuflen > 0) 241cb0ef41Sopenharmony_ci recvbuf = Buffer.alloc(recvbuflen); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci switch (type) { 271cb0ef41Sopenharmony_ci case 'buf': 281cb0ef41Sopenharmony_ci chunk = Buffer.alloc(sendchunklen, 'x'); 291cb0ef41Sopenharmony_ci break; 301cb0ef41Sopenharmony_ci case 'utf': 311cb0ef41Sopenharmony_ci encoding = 'utf8'; 321cb0ef41Sopenharmony_ci chunk = 'ü'.repeat(sendchunklen / 2); 331cb0ef41Sopenharmony_ci break; 341cb0ef41Sopenharmony_ci case 'asc': 351cb0ef41Sopenharmony_ci encoding = 'ascii'; 361cb0ef41Sopenharmony_ci chunk = 'x'.repeat(sendchunklen); 371cb0ef41Sopenharmony_ci break; 381cb0ef41Sopenharmony_ci default: 391cb0ef41Sopenharmony_ci throw new Error(`invalid type: ${type}`); 401cb0ef41Sopenharmony_ci } 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci const reader = new Reader(); 431cb0ef41Sopenharmony_ci let writer; 441cb0ef41Sopenharmony_ci let socketOpts; 451cb0ef41Sopenharmony_ci if (recvbuf === undefined) { 461cb0ef41Sopenharmony_ci writer = new Writer(); 471cb0ef41Sopenharmony_ci socketOpts = { port: PORT }; 481cb0ef41Sopenharmony_ci } else { 491cb0ef41Sopenharmony_ci let buffer = recvbuf; 501cb0ef41Sopenharmony_ci if (recvbufgenfn === 'true') { 511cb0ef41Sopenharmony_ci let bufidx = -1; 521cb0ef41Sopenharmony_ci const bufpool = [ 531cb0ef41Sopenharmony_ci recvbuf, 541cb0ef41Sopenharmony_ci Buffer.from(recvbuf), 551cb0ef41Sopenharmony_ci Buffer.from(recvbuf), 561cb0ef41Sopenharmony_ci ]; 571cb0ef41Sopenharmony_ci buffer = () => { 581cb0ef41Sopenharmony_ci bufidx = (bufidx + 1) % bufpool.length; 591cb0ef41Sopenharmony_ci return bufpool[bufidx]; 601cb0ef41Sopenharmony_ci }; 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci socketOpts = { 631cb0ef41Sopenharmony_ci port: PORT, 641cb0ef41Sopenharmony_ci onread: { 651cb0ef41Sopenharmony_ci buffer, 661cb0ef41Sopenharmony_ci callback: function(nread, buf) { 671cb0ef41Sopenharmony_ci received += nread; 681cb0ef41Sopenharmony_ci }, 691cb0ef41Sopenharmony_ci }, 701cb0ef41Sopenharmony_ci }; 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci // The actual benchmark. 741cb0ef41Sopenharmony_ci const server = net.createServer((socket) => { 751cb0ef41Sopenharmony_ci reader.pipe(socket); 761cb0ef41Sopenharmony_ci }); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci server.listen(PORT, () => { 791cb0ef41Sopenharmony_ci const socket = net.connect(socketOpts); 801cb0ef41Sopenharmony_ci socket.on('connect', () => { 811cb0ef41Sopenharmony_ci bench.start(); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci if (recvbuf === undefined) 841cb0ef41Sopenharmony_ci socket.pipe(writer); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci setTimeout(() => { 871cb0ef41Sopenharmony_ci const bytes = received; 881cb0ef41Sopenharmony_ci const gbits = (bytes * 8) / (1024 * 1024 * 1024); 891cb0ef41Sopenharmony_ci bench.end(gbits); 901cb0ef41Sopenharmony_ci process.exit(0); 911cb0ef41Sopenharmony_ci }, dur * 1000); 921cb0ef41Sopenharmony_ci }); 931cb0ef41Sopenharmony_ci }); 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ciconst net = require('net'); 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_cifunction Writer() { 991cb0ef41Sopenharmony_ci this.writable = true; 1001cb0ef41Sopenharmony_ci} 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ciWriter.prototype.write = function(chunk, encoding, cb) { 1031cb0ef41Sopenharmony_ci received += chunk.length; 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci if (typeof encoding === 'function') 1061cb0ef41Sopenharmony_ci encoding(); 1071cb0ef41Sopenharmony_ci else if (typeof cb === 'function') 1081cb0ef41Sopenharmony_ci cb(); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci return true; 1111cb0ef41Sopenharmony_ci}; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci// Doesn't matter, never emits anything. 1141cb0ef41Sopenharmony_ciWriter.prototype.on = function() {}; 1151cb0ef41Sopenharmony_ciWriter.prototype.once = function() {}; 1161cb0ef41Sopenharmony_ciWriter.prototype.emit = function() {}; 1171cb0ef41Sopenharmony_ciWriter.prototype.prependListener = function() {}; 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_cifunction flow() { 1211cb0ef41Sopenharmony_ci const dest = this.dest; 1221cb0ef41Sopenharmony_ci const res = dest.write(chunk, encoding); 1231cb0ef41Sopenharmony_ci if (!res) 1241cb0ef41Sopenharmony_ci dest.once('drain', this.flow); 1251cb0ef41Sopenharmony_ci else 1261cb0ef41Sopenharmony_ci process.nextTick(this.flow); 1271cb0ef41Sopenharmony_ci} 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_cifunction Reader() { 1301cb0ef41Sopenharmony_ci this.flow = flow.bind(this); 1311cb0ef41Sopenharmony_ci this.readable = true; 1321cb0ef41Sopenharmony_ci} 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ciReader.prototype.pipe = function(dest) { 1351cb0ef41Sopenharmony_ci this.dest = dest; 1361cb0ef41Sopenharmony_ci this.flow(); 1371cb0ef41Sopenharmony_ci return dest; 1381cb0ef41Sopenharmony_ci}; 139