1// In this benchmark, we connect a client to the server, and write 2// as many bytes as we can in the specified time (default = 10s) 3'use strict'; 4 5const common = require('../common.js'); 6const util = require('util'); 7 8// If there are --dur=N and --len=N args, then 9// run the function with those settings. 10// if not, then queue up a bunch of child processes. 11const bench = common.createBenchmark(main, { 12 len: [102400, 1024 * 1024 * 16], 13 type: ['utf', 'asc', 'buf'], 14 dur: [5] 15}, { 16 test: { len: 1024 }, 17 flags: [ '--expose-internals', '--no-warnings' ] 18}); 19 20function main({ dur, len, type }) { 21 const { 22 TCP, 23 TCPConnectWrap, 24 constants: TCPConstants 25 } = common.binding('tcp_wrap'); 26 const { WriteWrap } = common.binding('stream_wrap'); 27 const PORT = common.PORT; 28 29 function fail(err, syscall) { 30 throw util._errnoException(err, syscall); 31 } 32 33 // Server 34 const serverHandle = new TCP(TCPConstants.SERVER); 35 let err = serverHandle.bind('127.0.0.1', PORT); 36 if (err) 37 fail(err, 'bind'); 38 39 err = serverHandle.listen(511); 40 if (err) 41 fail(err, 'listen'); 42 43 serverHandle.onconnection = function(err, clientHandle) { 44 if (err) 45 fail(err, 'connect'); 46 47 clientHandle.onread = function(buffer) { 48 // We're not expecting to ever get an EOF from the client. 49 // Just lots of data forever. 50 if (!buffer) 51 fail('read'); 52 53 const writeReq = new WriteWrap(); 54 writeReq.async = false; 55 err = clientHandle.writeBuffer(writeReq, Buffer.from(buffer)); 56 57 if (err) 58 fail(err, 'write'); 59 60 writeReq.oncomplete = function(status, handle, err) { 61 if (err) 62 fail(err, 'write'); 63 }; 64 }; 65 66 clientHandle.readStart(); 67 }; 68 69 // Client 70 let chunk; 71 switch (type) { 72 case 'buf': 73 chunk = Buffer.alloc(len, 'x'); 74 break; 75 case 'utf': 76 chunk = 'ü'.repeat(len / 2); 77 break; 78 case 'asc': 79 chunk = 'x'.repeat(len); 80 break; 81 default: 82 throw new Error(`invalid type: ${type}`); 83 } 84 85 const clientHandle = new TCP(TCPConstants.SOCKET); 86 const connectReq = new TCPConnectWrap(); 87 let bytes = 0; 88 89 err = clientHandle.connect(connectReq, '127.0.0.1', PORT); 90 if (err) 91 fail(err, 'connect'); 92 93 clientHandle.onread = function(buffer) { 94 if (!buffer) 95 fail('read'); 96 97 bytes += buffer.byteLength; 98 }; 99 100 connectReq.oncomplete = function(err) { 101 if (err) 102 fail(err, 'connect'); 103 104 bench.start(); 105 106 clientHandle.readStart(); 107 108 setTimeout(() => { 109 // Multiply by 2 since we're sending it first one way 110 // then back again. 111 bench.end(2 * (bytes * 8) / (1024 * 1024 * 1024)); 112 process.exit(0); 113 }, dur * 1000); 114 115 while (clientHandle.writeQueueSize === 0) 116 write(); 117 }; 118 119 function write() { 120 const writeReq = new WriteWrap(); 121 writeReq.oncomplete = afterWrite; 122 let err; 123 switch (type) { 124 case 'buf': 125 err = clientHandle.writeBuffer(writeReq, chunk); 126 break; 127 case 'utf': 128 err = clientHandle.writeUtf8String(writeReq, chunk); 129 break; 130 case 'asc': 131 err = clientHandle.writeAsciiString(writeReq, chunk); 132 break; 133 } 134 135 if (err) 136 fail(err, 'write'); 137 } 138 139 function afterWrite(err, handle) { 140 if (err) 141 fail(err, 'write'); 142 143 while (clientHandle.writeQueueSize === 0) 144 write(); 145 } 146} 147