This repository was archived by the owner on Feb 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathbw.js
101 lines (89 loc) · 2.75 KB
/
bw.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict'
const { default: parseDuration } = require('parse-duration')
const errCode = require('err-code')
const withTimeoutOption = require('ipfs-core-utils/src/with-timeout-option')
/**
* @typedef {Object} BWOptions
* @property {PeerId} [peer] - Specifies a peer to print bandwidth for
* @property {string} [proto] - Specifies a protocol to print bandwidth for
* @property {boolean} [poll] - Is used to yield bandwidth info at an interval
* @property {number|string} [interval=1000] - The time interval to wait between updating output, if `poll` is `true`.
*
* @typedef {Object} BandwidthInfo
* @property {bigint} totalIn
* @property {bigint} totalOut
* @property {number} rateIn
* @property {number} rateOut
*
* @typedef {import('libp2p')} libp2p
* @typedef {import('peer-id')} PeerId
* @typedef {import('multiformats/cid').CID} CID
* @typedef {import('ipfs-core-types/src/utils').AbortOptions} AbortOptions
*/
/**
* @param {libp2p} libp2p
* @param {BWOptions} opts
* @returns {BandwidthInfo}
*/
function getBandwidthStats (libp2p, opts) {
let stats
if (!libp2p.metrics) {
stats = undefined
} else if (opts.peer) {
stats = libp2p.metrics.forPeer(opts.peer)
} else if (opts.proto) {
stats = libp2p.metrics.forProtocol(opts.proto)
} else {
stats = libp2p.metrics.global
}
if (!stats) {
return {
totalIn: BigInt(0),
totalOut: BigInt(0),
rateIn: 0.0,
rateOut: 0.0
}
}
const { movingAverages, snapshot } = stats
return {
totalIn: BigInt(snapshot.dataReceived.integerValue().toString()),
totalOut: BigInt(snapshot.dataSent.integerValue().toString()),
rateIn: movingAverages.dataReceived[60000].movingAverage() / 60,
rateOut: movingAverages.dataSent[60000].movingAverage() / 60
}
}
/**
* @param {Object} config
* @param {import('../../types').NetworkService} config.network
*/
module.exports = ({ network }) => {
/**
* @type {import('ipfs-core-types/src/stats').API["bw"]}
*/
const bw = async function * (options = {}) {
const { libp2p } = await network.use(options)
if (!options.poll) {
yield getBandwidthStats(libp2p, options)
return
}
const interval = options.interval || 1000
let ms = -1
try {
ms = typeof interval === 'string' ? parseDuration(interval) || -1 : interval
if (!ms || ms < 0) throw new Error('invalid duration')
} catch (err) {
throw errCode(err, 'ERR_INVALID_POLL_INTERVAL')
}
let timeoutId
try {
while (true) {
yield getBandwidthStats(libp2p, options)
// eslint-disable-next-line no-loop-func
await new Promise(resolve => { timeoutId = setTimeout(resolve, ms) })
}
} finally {
clearTimeout(timeoutId)
}
}
return withTimeoutOption(bw)
}