Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

refactor: convert stats API to async/await #2676

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/core/components/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,12 @@ function createApi ({
add,
config: Commands.config({ repo }),
init: () => { throw new AlreadyInitializedError() },
start
start,
stats: {
bitswap: () => { throw new NotStartedError() },
bw: () => { throw new NotStartedError() },
repo: Commands.repo.stat({ repo })
}
}

return api
Expand Down
5 changes: 5 additions & 0 deletions src/core/components/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ function createApi ({
config: Commands.config({ repo }),
init: () => { throw new AlreadyInitializedError() },
start: () => apiManager.api,
stats: {
bitswap: Commands.bitswap.stat({ bitswap }),
bw: Commands.stats.bw({ libp2p }),
repo: Commands.repo.stat({ repo })
},
stop
}

Expand Down
83 changes: 0 additions & 83 deletions src/core/components/stats.js

This file was deleted.

63 changes: 63 additions & 0 deletions src/core/components/stats/bw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
'use strict'

const Big = require('bignumber.js')
const human = require('human-to-milliseconds')
const errCode = require('err-code')

function getBandwidthStats (libp2p, opts) {
let stats

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: new Big(0),
totalOut: new Big(0),
rateIn: new Big(0),
rateOut: new Big(0)
}
}

const { movingAverages, snapshot } = stats

return {
totalIn: snapshot.dataReceived,
totalOut: snapshot.dataSent,
rateIn: new Big(movingAverages.dataReceived[60000].movingAverage() / 60),
rateOut: new Big(movingAverages.dataSent[60000].movingAverage() / 60)
}
}

module.exports = ({ libp2p }) => {
return async function * (options) {
options = options || {}

if (!options.poll) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a poll option feels slightly strange to me. I wonder if it would make sense to have two different methods:

  • stats() that returns a single value
  • poll() that is async iterable

Copy link
Member Author

@alanshaw alanshaw Dec 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree...

I'm not sold on the suggestion...ipfs.stats.bw.stats() doesn't read well to me! It would be nice to have a convention for APIs where we want to expose a one shot request/response but also a live streaming version...

// Single shot:
const stat = await ipfs.stats.bw()

// Live feed:
for await (const stat of ipfs.stats.bw.feed()) {
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha yes that sounds much better :)

yield getBandwidthStats(libp2p, options)
return
}

let interval
try {
interval = human(options.interval || '1s')
} catch (err) {
throw errCode(err, 'ERR_INVALID_POLL_INTERVAL')
}

let timeoutId
try {
while (true) {
yield getBandwidthStats(libp2p, options)
await new Promise(resolve => { timeoutId = setTimeout(resolve, interval) })
}
} finally {
clearTimeout(timeoutId)
}
}
}
5 changes: 5 additions & 0 deletions src/core/components/stop.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ function createApi ({
config: Commands.config({ repo }),
init: () => { throw new AlreadyInitializedError() },
start,
stats: {
bitswap: () => { throw new NotStartedError() },
bw: () => { throw new NotStartedError() },
repo: Commands.repo.stat({ repo })
},
stop: () => apiManager.api
}

Expand Down