• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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