1 | const { promisify } = require('util')
|
2 | const nanobench = require('nanobench')
|
3 | const pump = require('pump')
|
4 | const LatencyStream = require('latency-stream')
|
5 | const HypercoreProtocol = require('hypercore-protocol')
|
6 |
|
7 | const replicateAll = require('../test/helpers/replicate')
|
8 | const create = require('../test/helpers/create')
|
9 | const { runAll } = require('../test/helpers/util')
|
10 |
|
11 | nanobench('first read, 50ms latency', async b => {
|
12 | const LATENCY = 50
|
13 | const source = create()
|
14 | var dest, s1, s2
|
15 |
|
16 | source.ready(() => {
|
17 | dest = create(source.key)
|
18 | dest.ready(() => {
|
19 | return configure()
|
20 | })
|
21 | })
|
22 |
|
23 | function configure () {
|
24 | source.writeFile('hello', 'world', () => {
|
25 | source.writeFile('something', 'other', () => {
|
26 | return reconnect(bench)
|
27 | })
|
28 | })
|
29 | }
|
30 |
|
31 | function reconnect (cb) {
|
32 | if (s1) {
|
33 | s1.destroy()
|
34 | s2.destroy()
|
35 | s2.on('close', connect)
|
36 | } else {
|
37 | return connect()
|
38 | }
|
39 |
|
40 | function connect () {
|
41 | s1 = new HypercoreProtocol(true, { live: true })
|
42 | s2 = new HypercoreProtocol(false, { live: true })
|
43 | pump(s1, new LatencyStream([LATENCY, LATENCY]), s2, new LatencyStream([LATENCY, LATENCY]), s1, err => {
|
44 |
|
45 | })
|
46 | s1.on('handshake', cb)
|
47 | }
|
48 | }
|
49 |
|
50 | function bench () {
|
51 | console.time('first-read')
|
52 | b.start()
|
53 | dest.readFile('hello', () => {
|
54 | b.end()
|
55 | })
|
56 | source.replicate({ stream: s1, live: true })
|
57 | dest.replicate({ stream: s2, live: true })
|
58 | }
|
59 | })
|
60 |
|
61 | nanobench('subsequent read, 50ms latency', async b => {
|
62 | const LATENCY = 50
|
63 | const source = create()
|
64 | var dest, s1, s2
|
65 |
|
66 | source.ready(() => {
|
67 | dest = create(source.key)
|
68 | dest.ready(() => {
|
69 | return configure()
|
70 | })
|
71 | })
|
72 |
|
73 | function configure () {
|
74 | source.writeFile('hello', 'world', () => {
|
75 | source.writeFile('something', 'other', () => {
|
76 | return reconnect(bench)
|
77 | })
|
78 | })
|
79 | }
|
80 |
|
81 | function reconnect (cb) {
|
82 | if (s1) {
|
83 | s1.destroy()
|
84 | s2.destroy()
|
85 | s2.on('close', connect)
|
86 | } else {
|
87 | return connect()
|
88 | }
|
89 |
|
90 | function connect () {
|
91 | s1 = new HypercoreProtocol(true, { live: true })
|
92 | s2 = new HypercoreProtocol(false, { live: true })
|
93 | pump(s1, new LatencyStream([LATENCY, LATENCY]), s2, new LatencyStream([LATENCY, LATENCY]), s1, err => {
|
94 |
|
95 | })
|
96 | s1.on('handshake', cb)
|
97 | }
|
98 | }
|
99 |
|
100 | function bench () {
|
101 | dest.readFile('hello', err => {
|
102 | return reconnect(() => {
|
103 | b.start()
|
104 | source.replicate({ stream: s1, live: true })
|
105 | dest.replicate({ stream: s2, live: true })
|
106 | dest.readFile('something', () => {
|
107 | b.end()
|
108 | })
|
109 | })
|
110 | })
|
111 | source.replicate({ stream: s1, live: true })
|
112 | dest.replicate({ stream: s2, live: true })
|
113 | }
|
114 | })
|
115 |
|
116 | nanobench('subsequent seek, 50ms latency', async b => {
|
117 | const LATENCY = 50
|
118 | const source = create()
|
119 | var dest, s1, s2
|
120 |
|
121 | source.ready(() => {
|
122 | dest = create(source.key)
|
123 | dest.ready(() => {
|
124 | return configure()
|
125 | })
|
126 | })
|
127 |
|
128 | function configure () {
|
129 | source.writeFile('hello', 'world', () => {
|
130 | source.writeFile('something', Buffer.allocUnsafe(1024 * 1024).fill('abc123'), () => {
|
131 | return reconnect(bench)
|
132 | })
|
133 | })
|
134 | }
|
135 |
|
136 | function reconnect (cb) {
|
137 | if (s1) {
|
138 | s1.destroy()
|
139 | s2.destroy()
|
140 | s2.on('close', connect)
|
141 | } else {
|
142 | return connect()
|
143 | }
|
144 |
|
145 | function connect () {
|
146 | s1 = new HypercoreProtocol(true, { live: true })
|
147 | s2 = new HypercoreProtocol(false, { live: true })
|
148 | pump(s1, new LatencyStream([LATENCY, LATENCY]), s2, new LatencyStream([LATENCY, LATENCY]), s1, err => {
|
149 |
|
150 | })
|
151 | s1.on('handshake', cb)
|
152 | }
|
153 | }
|
154 |
|
155 | function bench () {
|
156 | dest.readFile('hello', err => {
|
157 | return reconnect(() => {
|
158 | b.start()
|
159 | source.replicate({ stream: s1, live: true })
|
160 | dest.replicate({ stream: s2, live: true })
|
161 | dest.open('something', 'r', (_, fd) => {
|
162 | dest.read(fd, Buffer.allocUnsafe(1024), 0, 1024, 1024 * 800, () => {
|
163 | b.end()
|
164 | })
|
165 | })
|
166 | })
|
167 | })
|
168 | source.replicate({ stream: s1, live: true })
|
169 | dest.replicate({ stream: s2, live: true })
|
170 | }
|
171 | })
|
172 |
|
173 | nanobench('reading the same file twice, 50ms latency', async b => {
|
174 | const LATENCY = 50
|
175 | const source = create()
|
176 | var dest, s1, s2
|
177 |
|
178 | source.ready(() => {
|
179 | dest = create(source.key)
|
180 | dest.ready(() => {
|
181 | return configure()
|
182 | })
|
183 | })
|
184 |
|
185 | function configure () {
|
186 | source.writeFile('hello', 'world', () => {
|
187 | source.writeFile('something', 'other', () => {
|
188 | return reconnect(bench)
|
189 | })
|
190 | })
|
191 | }
|
192 |
|
193 | function reconnect (cb) {
|
194 | if (s1) {
|
195 | s1.destroy()
|
196 | s2.destroy()
|
197 | s2.on('close', connect)
|
198 | } else {
|
199 | return connect()
|
200 | }
|
201 |
|
202 | function connect () {
|
203 | s1 = new HypercoreProtocol(true, { live: true })
|
204 | s2 = new HypercoreProtocol(false, { live: true })
|
205 | pump(s1, new LatencyStream([LATENCY, LATENCY]), s2, new LatencyStream([LATENCY, LATENCY]), s1, err => {
|
206 |
|
207 | })
|
208 | s1.on('handshake', cb)
|
209 | }
|
210 | }
|
211 |
|
212 | function bench () {
|
213 | dest.readFile('hello', () => {
|
214 | return reconnect(() => {
|
215 | b.start()
|
216 | source.replicate({ stream: s1, live: true })
|
217 | dest.replicate({ stream: s2, live: true })
|
218 | dest.readFile('hello', () => {
|
219 | b.end()
|
220 | })
|
221 | })
|
222 | })
|
223 | source.replicate({ stream: s1, live: true })
|
224 | dest.replicate({ stream: s2, live: true })
|
225 | }
|
226 | })
|
227 |
|
228 | nanobench('listing a directory with 100 files, 50ms latency', async b => {
|
229 | const LATENCY = 50
|
230 | const NUM_FILES = 100
|
231 |
|
232 | const source = create()
|
233 | var dest, s1, s2
|
234 |
|
235 | source.ready(() => {
|
236 | dest = create(source.key)
|
237 | dest.ready(() => {
|
238 | return configure()
|
239 | })
|
240 | })
|
241 |
|
242 | async function configure () {
|
243 | const files = (new Array(NUM_FILES)).fill(0).map((_, i) => '' + i)
|
244 | await runAll(files.map(name => {
|
245 | return cb => source.writeFile(name, name, cb)
|
246 | }))
|
247 | return reconnect(bench)
|
248 | }
|
249 |
|
250 | function reconnect (cb) {
|
251 | if (s1) {
|
252 | s1.destroy()
|
253 | s2.destroy()
|
254 | s2.on('close', connect)
|
255 | } else {
|
256 | return connect()
|
257 | }
|
258 |
|
259 | function connect () {
|
260 | s1 = new HypercoreProtocol(true, { live: true })
|
261 | s2 = new HypercoreProtocol(false, { live: true })
|
262 | pump(s1, new LatencyStream([LATENCY, LATENCY]), s2, new LatencyStream([LATENCY, LATENCY]), s1, err => {
|
263 |
|
264 | })
|
265 | s1.on('handshake', cb)
|
266 | }
|
267 | }
|
268 |
|
269 | function bench () {
|
270 | dest.readFile('0', () => {
|
271 | b.start()
|
272 | dest.readdir('/', (err, list) => {
|
273 | b.end()
|
274 | })
|
275 | })
|
276 | source.replicate({ stream: s1, live: true })
|
277 | dest.replicate({ stream: s2, live: true })
|
278 | }
|
279 | })
|