hyperdrive-profiler 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bare-bin.js +3 -0
- package/bin.js +1 -190
- package/index.js +192 -0
- package/package.json +8 -5
- package/bare-bin.sh +0 -3
package/bare-bin.js
ADDED
package/bin.js
CHANGED
|
@@ -1,192 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const fs = require('fs')
|
|
5
|
-
const os = require('os')
|
|
6
|
-
const path = require('path')
|
|
7
|
-
const { performance } = require('perf_hooks')
|
|
8
|
-
|
|
9
|
-
const { command, arg, flag } = require('paparam')
|
|
10
|
-
const goodbye = require('graceful-goodbye')
|
|
11
|
-
const IdEnc = require('hypercore-id-encoding')
|
|
12
|
-
const Corestore = require('corestore')
|
|
13
|
-
const Hyperdrive = require('hyperdrive')
|
|
14
|
-
const Hyperswarm = require('hyperswarm')
|
|
15
|
-
const HypercoreStats = require('hypercore-stats')
|
|
16
|
-
const HyperswarmStats = require('hyperswarm-stats')
|
|
17
|
-
const byteSize = require('tiny-byte-size')
|
|
18
|
-
|
|
19
|
-
const cmd = command('hyperdrive-profiler',
|
|
20
|
-
arg('<key>', 'Public key of the hyperdrive to download'),
|
|
21
|
-
flag('--interval|-i [integer]', 'Interval (in seconds) at which to print the performance stats (default 10)'),
|
|
22
|
-
flag('--ip', 'Print the IP address (obfuscated by default)'),
|
|
23
|
-
flag('--detail', 'Include detailed stats'),
|
|
24
|
-
|
|
25
|
-
async function ({ args, flags }) {
|
|
26
|
-
const key = IdEnc.decode(args.key)
|
|
27
|
-
const statsIntervalMs = 1000 * (parseInt(flags.interval || 10))
|
|
28
|
-
const printIp = flags.ip
|
|
29
|
-
const detail = flags.detail
|
|
30
|
-
|
|
31
|
-
const tStart = performance.now()
|
|
32
|
-
let secTillMetadata = null
|
|
33
|
-
let secTillFullyDownload = null
|
|
34
|
-
|
|
35
|
-
const tmpdir = path.join(os.tmpdir(), `hyperdrive-profiler-tmp-${Math.random().toString(16).slice(2)}`)
|
|
36
|
-
console.info(`Profiling hyperdrive download for ${IdEnc.normalize(key)}`)
|
|
37
|
-
console.info(`Using temporary directory ${tmpdir}`)
|
|
38
|
-
console.info(`Printing progress every ${(statsIntervalMs / 1000).toFixed(0)} seconds`)
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
await gcDir(tmpdir)
|
|
42
|
-
} catch {}
|
|
43
|
-
|
|
44
|
-
await fs.promises.mkdir(tmpdir)
|
|
45
|
-
|
|
46
|
-
const store = new Corestore(tmpdir)
|
|
47
|
-
|
|
48
|
-
const hypercoreStats = await HypercoreStats.fromCorestore(store, { cacheExpiryMs: 1000 })
|
|
49
|
-
|
|
50
|
-
const drive = new Hyperdrive(store, key)
|
|
51
|
-
const swarm = new Hyperswarm()
|
|
52
|
-
swarm.on('connection', conn => {
|
|
53
|
-
store.replicate(conn)
|
|
54
|
-
conn.on('error', (e) => {
|
|
55
|
-
console.log(`Connection error: ${e.stack}`)
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
const swarmStats = new HyperswarmStats(swarm)
|
|
60
|
-
|
|
61
|
-
const printStats = () => {
|
|
62
|
-
const elapsedSec = (performance.now() - tStart) / 1000
|
|
63
|
-
|
|
64
|
-
let timestampsInfo = `General\n - Runtime: ${elapsedSec.toFixed(2)} seconds`
|
|
65
|
-
timestampsInfo += '\n - Metadata found in: '
|
|
66
|
-
timestampsInfo += secTillMetadata
|
|
67
|
-
? `${secTillMetadata.toFixed(2).toString()} seconds`
|
|
68
|
-
: 'unknown (still connecting...)'
|
|
69
|
-
if (secTillFullyDownload) timestampsInfo += `\n - Fully downloaded in ${secTillFullyDownload.toFixed(2)} seconds`
|
|
70
|
-
|
|
71
|
-
const udxInfo = getUdxInfo(swarmStats, elapsedSec)
|
|
72
|
-
const swarmInfo = getSwarmInfo(swarmStats, { printIp, detail })
|
|
73
|
-
const hypercoreInfo = getHypercoreInfo(hypercoreStats, { detail })
|
|
74
|
-
console.log(`${timestampsInfo}\n${udxInfo}${swarmInfo}${hypercoreInfo}`)
|
|
75
|
-
console.log(`${'-'.repeat(50)}\n`)
|
|
76
|
-
}
|
|
77
|
-
const statsInterval = setInterval(printStats, statsIntervalMs)
|
|
78
|
-
|
|
79
|
-
let cancelling = true
|
|
80
|
-
goodbye(async () => {
|
|
81
|
-
printStats()
|
|
82
|
-
if (cancelling) console.info('Cancelling before the download is complete...')
|
|
83
|
-
clearInterval(statsInterval)
|
|
84
|
-
|
|
85
|
-
console.log('Destroying swarm...')
|
|
86
|
-
await swarm.destroy()
|
|
87
|
-
console.log('Closing corestore...')
|
|
88
|
-
await store.close()
|
|
89
|
-
console.info('Cleaning up temporary directory...')
|
|
90
|
-
await gcDir(tmpdir)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
await drive.ready()
|
|
94
|
-
|
|
95
|
-
swarm.join(drive.discoveryKey, { server: false, client: true })
|
|
96
|
-
if (drive.db.core.length <= 1) await once(drive.db.core, 'append') // DEVNOTE: in theory we could get a not-latest length, but 'good enough'
|
|
97
|
-
secTillMetadata = (performance.now() - tStart) / 1000
|
|
98
|
-
|
|
99
|
-
console.info(`Downloading drive version ${drive.version}`)
|
|
100
|
-
console.log(`\n${'-'.repeat(50)}\n`)
|
|
101
|
-
await drive.download('/', { wait: true }).done()
|
|
102
|
-
|
|
103
|
-
secTillFullyDownload = (performance.now() - tStart) / 1000
|
|
104
|
-
cancelling = false
|
|
105
|
-
goodbye.exit()
|
|
106
|
-
}
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
async function gcDir (dir) {
|
|
110
|
-
await fs.promises.rm(dir, { recursive: true })
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function getHypercoreInfo (stats, { detail }) {
|
|
114
|
-
let res = `Hypercore stats
|
|
115
|
-
- Hotswaps: ${stats.totalHotswaps}
|
|
116
|
-
`
|
|
117
|
-
if (detail) {
|
|
118
|
-
res += ` - Commands:
|
|
119
|
-
- Sync: ${stats.totalWireSyncReceived} received / ${stats.totalWireSyncTransmitted} transmitted
|
|
120
|
-
- Request: ${stats.totalWireRequestReceived} received / ${stats.totalWireRequestTransmitted} transmitted
|
|
121
|
-
- Cancel: ${stats.totalWireCancelReceived} received / ${stats.totalWireCancelTransmitted} transmitted
|
|
122
|
-
- Data: ${stats.totalWireDataReceived} received / ${stats.totalWireDataTransmitted} transmitted
|
|
123
|
-
- Want: ${stats.totalWireWantReceived} received / ${stats.totalWireWantTransmitted} transmitted
|
|
124
|
-
- Bitfield: ${stats.totalWireBitfieldReceived} received / ${stats.totalWireBitfieldTransmitted} transmitted
|
|
125
|
-
- Range: ${stats.totalWireRangeReceived} received / ${stats.totalWireRangeTransmitted} transmitted
|
|
126
|
-
- Extension: ${stats.totalWireExtensionReceived} received / ${stats.totalWireExtensionTransmitted} transmitted
|
|
127
|
-
`
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return res
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function getSwarmInfo (swarmStats, { printIp, detail }) {
|
|
134
|
-
const address = printIp
|
|
135
|
-
? swarmStats.dhtStats.getRemoteAddress()
|
|
136
|
-
: 'xxx.xxx.xxx.xxx'
|
|
137
|
-
const firewalled = swarmStats.dhtStats.isFirewalled
|
|
138
|
-
let res = `Connection info
|
|
139
|
-
- Address: ${address} (firewalled: ${firewalled})
|
|
140
|
-
- Connections:
|
|
141
|
-
- Attempted: ${swarmStats.connects.client.attempted}
|
|
142
|
-
- Opened: ${swarmStats.connects.client.opened}
|
|
143
|
-
- Closed: ${swarmStats.connects.client.closed}
|
|
144
|
-
- Connection issues:
|
|
145
|
-
- Retransmission timeouts: ${swarmStats.getRTOCountAcrossAllStreams()}
|
|
146
|
-
- Fast recoveries: ${swarmStats.getFastRecoveriesAcrossAllStreams()}
|
|
147
|
-
- Retransmits: ${swarmStats.getRetransmitsAcrossAllStreams()}
|
|
148
|
-
`
|
|
149
|
-
|
|
150
|
-
if (detail) {
|
|
151
|
-
const { consistent, random, open } = swarmStats.dhtStats.punches
|
|
152
|
-
res += ` - Punches:
|
|
153
|
-
- Consistent: ${consistent}
|
|
154
|
-
- Random: ${random}
|
|
155
|
-
- Open: ${open}
|
|
156
|
-
`
|
|
157
|
-
|
|
158
|
-
res += ` - Total Queries: ${swarmStats.dhtStats.queries.total}
|
|
159
|
-
- DHT commands
|
|
160
|
-
- Ping: ${swarmStats.dhtStats.pingCmds.rx} received / ${swarmStats.dhtStats.pingCmds.tx} transmitted
|
|
161
|
-
- Ping NAT: ${swarmStats.dhtStats.pingNatCmds.rx} received / ${swarmStats.dhtStats.pingNatCmds.tx} transmitted
|
|
162
|
-
- Down Hint: ${swarmStats.dhtStats.downHintCmds.rx} received / ${swarmStats.dhtStats.downHintCmds.tx} transmitted
|
|
163
|
-
- Find Node: ${swarmStats.dhtStats.findNodeCmds.rx} received / ${swarmStats.dhtStats.findNodeCmds.tx} transmitted
|
|
164
|
-
`
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return res
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function getUdxInfo (swarmStats, elapsedSec) {
|
|
171
|
-
const bytesRx = swarmStats.dhtStats.udxBytesReceived
|
|
172
|
-
const bytesRxPerSec = (bytesRx / elapsedSec).toFixed(2)
|
|
173
|
-
const bytesTx = swarmStats.dhtStats.udxBytesTransmitted
|
|
174
|
-
const bytesTxPerSec = (bytesTx / elapsedSec).toFixed(2)
|
|
175
|
-
const packetsRx = swarmStats.dhtStats.udxPacketsReceived
|
|
176
|
-
const packetsRxPerSec = (packetsRx / elapsedSec).toFixed(0)
|
|
177
|
-
const packetsTx = swarmStats.dhtStats.udxPacketsTransmitted
|
|
178
|
-
const packetsTxPerSec = (packetsTx / elapsedSec).toFixed(0)
|
|
179
|
-
|
|
180
|
-
const packetsDropped = swarmStats.dhtStats.udxPacketsDropped
|
|
181
|
-
const packetsDroppedPerSec = (packetsDropped / elapsedSec).toFixed(2)
|
|
182
|
-
|
|
183
|
-
return `Network (UDX)
|
|
184
|
-
- Bytes received: ${byteSize(bytesRx)} (${byteSize(bytesRxPerSec)} / second)
|
|
185
|
-
- Bytes transmitted: ${byteSize(bytesTx)} (${byteSize(bytesTxPerSec)} / second)
|
|
186
|
-
- Packets received: ${packetsRx} (${packetsRxPerSec} / second)
|
|
187
|
-
- Packets transmitted: ${packetsTx} (${packetsTxPerSec} / second)
|
|
188
|
-
- Packets dropped: ${swarmStats.dhtStats.udxPacketsDropped} (${packetsDroppedPerSec} / second)
|
|
189
|
-
`
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
cmd.parse()
|
|
3
|
+
require('.')
|
package/index.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
const { runtime } = require('which-runtime')
|
|
2
|
+
const { once } = require('events')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const os = require('os')
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const { performance } = require('perf_hooks')
|
|
7
|
+
|
|
8
|
+
const { command, arg, flag } = require('paparam')
|
|
9
|
+
const goodbye = require('graceful-goodbye')
|
|
10
|
+
const IdEnc = require('hypercore-id-encoding')
|
|
11
|
+
const Corestore = require('corestore')
|
|
12
|
+
const Hyperdrive = require('hyperdrive')
|
|
13
|
+
const Hyperswarm = require('hyperswarm')
|
|
14
|
+
const HypercoreStats = require('hypercore-stats')
|
|
15
|
+
const HyperswarmStats = require('hyperswarm-stats')
|
|
16
|
+
const byteSize = require('tiny-byte-size')
|
|
17
|
+
|
|
18
|
+
const cmd = command('hyperdrive-profiler',
|
|
19
|
+
arg('<key>', 'Public key of the hyperdrive to download'),
|
|
20
|
+
flag('--interval|-i [integer]', 'Interval (in seconds) at which to print the performance stats (default 10)'),
|
|
21
|
+
flag('--ip', 'Print the IP address (obfuscated by default)'),
|
|
22
|
+
flag('--detail', 'Include detailed stats'),
|
|
23
|
+
|
|
24
|
+
async function ({ args, flags }) {
|
|
25
|
+
const key = IdEnc.decode(args.key)
|
|
26
|
+
const statsIntervalMs = 1000 * (parseInt(flags.interval || 10))
|
|
27
|
+
const printIp = flags.ip
|
|
28
|
+
const detail = flags.detail
|
|
29
|
+
|
|
30
|
+
const tStart = performance.now()
|
|
31
|
+
let secTillMetadata = null
|
|
32
|
+
let secTillFullyDownload = null
|
|
33
|
+
|
|
34
|
+
const tmpdir = path.join(os.tmpdir(), `hyperdrive-profiler-tmp-${Math.random().toString(16).slice(2)}`)
|
|
35
|
+
console.info(`Profiling hyperdrive download for ${IdEnc.normalize(key)} using runtime: ${runtime}`)
|
|
36
|
+
console.info(`Using temporary directory ${tmpdir}`)
|
|
37
|
+
console.info(`Printing progress every ${(statsIntervalMs / 1000).toFixed(0)} seconds`)
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
await gcDir(tmpdir)
|
|
41
|
+
} catch {}
|
|
42
|
+
|
|
43
|
+
await fs.promises.mkdir(tmpdir)
|
|
44
|
+
|
|
45
|
+
const store = new Corestore(tmpdir)
|
|
46
|
+
|
|
47
|
+
const hypercoreStats = await HypercoreStats.fromCorestore(store, { cacheExpiryMs: 1000 })
|
|
48
|
+
|
|
49
|
+
const drive = new Hyperdrive(store, key)
|
|
50
|
+
const swarm = new Hyperswarm()
|
|
51
|
+
swarm.on('connection', conn => {
|
|
52
|
+
store.replicate(conn)
|
|
53
|
+
conn.on('error', (e) => {
|
|
54
|
+
console.log(`Connection error: ${e.stack}`)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const swarmStats = new HyperswarmStats(swarm)
|
|
59
|
+
|
|
60
|
+
const printStats = () => {
|
|
61
|
+
const elapsedSec = (performance.now() - tStart) / 1000
|
|
62
|
+
|
|
63
|
+
let timestampsInfo = `General\n - Runtime: ${elapsedSec.toFixed(2)} seconds`
|
|
64
|
+
timestampsInfo += '\n - Metadata found in: '
|
|
65
|
+
timestampsInfo += secTillMetadata
|
|
66
|
+
? `${secTillMetadata.toFixed(2).toString()} seconds`
|
|
67
|
+
: 'unknown (still connecting...)'
|
|
68
|
+
if (secTillFullyDownload) timestampsInfo += `\n - Fully downloaded in ${secTillFullyDownload.toFixed(2)} seconds`
|
|
69
|
+
|
|
70
|
+
const udxInfo = getUdxInfo(swarmStats, elapsedSec)
|
|
71
|
+
const swarmInfo = getSwarmInfo(swarmStats, { printIp, detail })
|
|
72
|
+
const hypercoreInfo = getHypercoreInfo(hypercoreStats, { detail })
|
|
73
|
+
console.log(`${timestampsInfo}\n${udxInfo}${swarmInfo}${hypercoreInfo}`)
|
|
74
|
+
console.log(`${'-'.repeat(50)}\n`)
|
|
75
|
+
}
|
|
76
|
+
const statsInterval = setInterval(printStats, statsIntervalMs)
|
|
77
|
+
|
|
78
|
+
let cancelling = true
|
|
79
|
+
goodbye(async () => {
|
|
80
|
+
printStats()
|
|
81
|
+
if (cancelling) console.info('Cancelling before the download is complete...')
|
|
82
|
+
clearInterval(statsInterval)
|
|
83
|
+
|
|
84
|
+
console.log('Destroying swarm...')
|
|
85
|
+
await swarm.destroy()
|
|
86
|
+
console.log('Closing corestore...')
|
|
87
|
+
await store.close()
|
|
88
|
+
console.info('Cleaning up temporary directory...')
|
|
89
|
+
await gcDir(tmpdir)
|
|
90
|
+
console.log('fully done...')
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
await drive.ready()
|
|
94
|
+
|
|
95
|
+
swarm.join(drive.discoveryKey, { server: false, client: true })
|
|
96
|
+
if (drive.db.core.length <= 1) await once(drive.db.core, 'append') // DEVNOTE: in theory we could get a not-latest length, but 'good enough'
|
|
97
|
+
secTillMetadata = (performance.now() - tStart) / 1000
|
|
98
|
+
|
|
99
|
+
console.info(`Downloading drive version ${drive.version}`)
|
|
100
|
+
console.log(`\n${'-'.repeat(50)}\n`)
|
|
101
|
+
await drive.download('/', { wait: true }).done()
|
|
102
|
+
|
|
103
|
+
secTillFullyDownload = (performance.now() - tStart) / 1000
|
|
104
|
+
cancelling = false
|
|
105
|
+
goodbye.exit()
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
async function gcDir (dir) {
|
|
110
|
+
await fs.promises.rm(dir, { recursive: true })
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getHypercoreInfo (stats, { detail }) {
|
|
114
|
+
let res = `Hypercore stats
|
|
115
|
+
- Hotswaps: ${stats.totalHotswaps}
|
|
116
|
+
`
|
|
117
|
+
if (detail) {
|
|
118
|
+
res += ` - Commands:
|
|
119
|
+
- Sync: ${stats.totalWireSyncReceived} received / ${stats.totalWireSyncTransmitted} transmitted
|
|
120
|
+
- Request: ${stats.totalWireRequestReceived} received / ${stats.totalWireRequestTransmitted} transmitted
|
|
121
|
+
- Cancel: ${stats.totalWireCancelReceived} received / ${stats.totalWireCancelTransmitted} transmitted
|
|
122
|
+
- Data: ${stats.totalWireDataReceived} received / ${stats.totalWireDataTransmitted} transmitted
|
|
123
|
+
- Want: ${stats.totalWireWantReceived} received / ${stats.totalWireWantTransmitted} transmitted
|
|
124
|
+
- Bitfield: ${stats.totalWireBitfieldReceived} received / ${stats.totalWireBitfieldTransmitted} transmitted
|
|
125
|
+
- Range: ${stats.totalWireRangeReceived} received / ${stats.totalWireRangeTransmitted} transmitted
|
|
126
|
+
- Extension: ${stats.totalWireExtensionReceived} received / ${stats.totalWireExtensionTransmitted} transmitted
|
|
127
|
+
`
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return res
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function getSwarmInfo (swarmStats, { printIp, detail }) {
|
|
134
|
+
const address = printIp
|
|
135
|
+
? swarmStats.dhtStats.getRemoteAddress()
|
|
136
|
+
: 'xxx.xxx.xxx.xxx'
|
|
137
|
+
const firewalled = swarmStats.dhtStats.isFirewalled
|
|
138
|
+
let res = `Connection info
|
|
139
|
+
- Address: ${address} (firewalled: ${firewalled})
|
|
140
|
+
- Connections:
|
|
141
|
+
- Attempted: ${swarmStats.connects.client.attempted}
|
|
142
|
+
- Opened: ${swarmStats.connects.client.opened}
|
|
143
|
+
- Closed: ${swarmStats.connects.client.closed}
|
|
144
|
+
- Connection issues:
|
|
145
|
+
- Retransmission timeouts: ${swarmStats.getRTOCountAcrossAllStreams()}
|
|
146
|
+
- Fast recoveries: ${swarmStats.getFastRecoveriesAcrossAllStreams()}
|
|
147
|
+
- Retransmits: ${swarmStats.getRetransmitsAcrossAllStreams()}
|
|
148
|
+
`
|
|
149
|
+
|
|
150
|
+
if (detail) {
|
|
151
|
+
const { consistent, random, open } = swarmStats.dhtStats.punches
|
|
152
|
+
res += ` - Punches:
|
|
153
|
+
- Consistent: ${consistent}
|
|
154
|
+
- Random: ${random}
|
|
155
|
+
- Open: ${open}
|
|
156
|
+
`
|
|
157
|
+
|
|
158
|
+
res += ` - Total Queries: ${swarmStats.dhtStats.queries.total}
|
|
159
|
+
- DHT commands
|
|
160
|
+
- Ping: ${swarmStats.dhtStats.pingCmds.rx} received / ${swarmStats.dhtStats.pingCmds.tx} transmitted
|
|
161
|
+
- Ping NAT: ${swarmStats.dhtStats.pingNatCmds.rx} received / ${swarmStats.dhtStats.pingNatCmds.tx} transmitted
|
|
162
|
+
- Down Hint: ${swarmStats.dhtStats.downHintCmds.rx} received / ${swarmStats.dhtStats.downHintCmds.tx} transmitted
|
|
163
|
+
- Find Node: ${swarmStats.dhtStats.findNodeCmds.rx} received / ${swarmStats.dhtStats.findNodeCmds.tx} transmitted
|
|
164
|
+
`
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return res
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function getUdxInfo (swarmStats, elapsedSec) {
|
|
171
|
+
const bytesRx = swarmStats.dhtStats.udxBytesReceived
|
|
172
|
+
const bytesRxPerSec = (bytesRx / elapsedSec).toFixed(2)
|
|
173
|
+
const bytesTx = swarmStats.dhtStats.udxBytesTransmitted
|
|
174
|
+
const bytesTxPerSec = (bytesTx / elapsedSec).toFixed(2)
|
|
175
|
+
const packetsRx = swarmStats.dhtStats.udxPacketsReceived
|
|
176
|
+
const packetsRxPerSec = (packetsRx / elapsedSec).toFixed(0)
|
|
177
|
+
const packetsTx = swarmStats.dhtStats.udxPacketsTransmitted
|
|
178
|
+
const packetsTxPerSec = (packetsTx / elapsedSec).toFixed(0)
|
|
179
|
+
|
|
180
|
+
const packetsDropped = swarmStats.dhtStats.udxPacketsDropped
|
|
181
|
+
const packetsDroppedPerSec = (packetsDropped / elapsedSec).toFixed(2)
|
|
182
|
+
|
|
183
|
+
return `Network (UDX)
|
|
184
|
+
- Bytes received: ${byteSize(bytesRx)} (${byteSize(bytesRxPerSec)} / second)
|
|
185
|
+
- Bytes transmitted: ${byteSize(bytesTx)} (${byteSize(bytesTxPerSec)} / second)
|
|
186
|
+
- Packets received: ${packetsRx} (${packetsRxPerSec} / second)
|
|
187
|
+
- Packets transmitted: ${packetsTx} (${packetsTxPerSec} / second)
|
|
188
|
+
- Packets dropped: ${swarmStats.dhtStats.udxPacketsDropped} (${packetsDroppedPerSec} / second)
|
|
189
|
+
`
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
cmd.parse()
|
package/package.json
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyperdrive-profiler",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Profile hyperdrive download performance",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "standard"
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
10
|
"hyperdrive-profiler": "bin.js",
|
|
11
|
-
"hyperdrive-profiler-bare": "bare-bin.
|
|
11
|
+
"hyperdrive-profiler-bare": "bare-bin.js"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
-
"bin.js"
|
|
14
|
+
"bin.js",
|
|
15
|
+
"bare-bin.js",
|
|
16
|
+
"index.js"
|
|
15
17
|
],
|
|
16
18
|
"repository": {
|
|
17
19
|
"type": "git",
|
|
@@ -45,7 +47,8 @@
|
|
|
45
47
|
"hyperswarm": "^4.8.4",
|
|
46
48
|
"hyperswarm-stats": "^1.2.0",
|
|
47
49
|
"paparam": "^1.8.0",
|
|
48
|
-
"tiny-byte-size": "^1.1.0"
|
|
50
|
+
"tiny-byte-size": "^1.1.0",
|
|
51
|
+
"which-runtime": "^1.3.0"
|
|
49
52
|
},
|
|
50
53
|
"imports": {
|
|
51
54
|
"events": {
|
package/bare-bin.sh
DELETED