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

Commit

Permalink
feat: add stats.bwPullStream and stats.bwReadableStream (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias authored and daviddias committed Feb 7, 2018
1 parent 328726a commit 4421eb2
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 82 deletions.
16 changes: 9 additions & 7 deletions SPEC/BITSWAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ Bitswap API

`callback` must follow `function (err, stats) {}` signature, where `err` is an error if the operation was not successful. `stats` is an Object containing the following keys:

- `provideBufLen`
- `provideBufLen` is an integer.
- `wantlist` (array)
- `peers` (array)
- `blocksReceived`
- `dataReceived`
- `blocksSent`
- `dataSent`
- `dupBlksReceived`
- `dupDataReceived`
- `blocksReceived` is a [Big Int][1]
- `dataReceived` is a [Big Int][1]
- `blocksSent` is a [Big Int][1]
- `dataSent` is a [Big Int][1]
- `dupBlksReceived` is a [Big Int][1]
- `dupDataReceived` is a [Big Int][1]

If no `callback` is passed, a promise is returned.

Expand All @@ -47,3 +47,5 @@ ipfs.stats.bitswap((err, stats) => console.log(stats))
// dupBlksReceived: 0,
// dupDataReceived: 0 }
```

[1]: https://github.com/MikeMcl/big.js/
12 changes: 7 additions & 5 deletions SPEC/REPO.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ Where:

`callback` must follow `function (err, stats) {}` signature, where `err` is an Error if the operation was not successful and `stats` is an object containing the following keys:

- `numObjects`
- `repoSize`
- `repoPath`
- `version`
- `storageMax`
- `numObjects` is a [Big Int][1].
- `repoSize` is a [Big Int][1], in bytes.
- `repoPath` is a string.
- `version` is a string.
- `storageMax` is a [Big Int][1].

If no `callback` is passed, a promise is returned.

Expand Down Expand Up @@ -81,3 +81,5 @@ ipfs.repo.version((err, version) => console.log(version))

// "6"
```

[1]: https://github.com/MikeMcl/big.js/
84 changes: 74 additions & 10 deletions SPEC/STATS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Stats API

#### `bw`

> Adds an IPFS object to the pinset and also stores it to the IPFS repo. pinset is the set of hashes currently pinned (not gc'able).
> Get IPFS bandwidth information as an object.
##### `Go` **WIP**

Expand All @@ -25,12 +25,14 @@ Where:
- `poll` is used to print bandwidth at an interval.
- `interval` is the time interval to wait between updating output, if `poll` is true.

`callback` must follow `function (err, stats) {}` signature, where `err` is an error if the operation was not successful. `stats` is an Object containing the following keys:
`callback` must follow `function (err, stat) {}` signature, where `err` is an Error if the operation was not successful.

- `totalIn`
- `totalOut`
- `rateIn`
- `rateOut`
`stat` is, in both cases, an Object containing the following keys:

- `totalIn` - is a [Big Int][big], in bytes.
- `totalOut` - is a [Big Int][big], in bytes.
- `rateIn` - is a [Big Int][big], in bytes.
- `rateOut` - is a [Big Int][big], in bytes.

If no `callback` is passed, a promise is returned.

Expand All @@ -39,8 +41,70 @@ If no `callback` is passed, a promise is returned.
```JavaScript
ipfs.stats.bw((err, stats) => console.log(stats))

// { totalIn: 15456,
// totalOut: 15420,
// rateIn: 905.0873512246716,
// rateOut: 893.7400053359125 }
// { totalIn: Big {...},
// totalOut: Big {...},
// rateIn: Big {...},
// rateOut: Big {...} }
```

#### `bwPullStream`

> Get IPFS bandwidth information as a [Pull Stream][ps].
##### `Go` **WIP**

##### `JavaScript` - ipfs.stats.bwPullStream([options]) -> [Pull Stream][ps]

Options are described on [`ipfs.stats.bw`](#bw).

**Example:**

```JavaScript
const pull = require('pull-stream')
const log = require('pull-stream/sinks/log')

const stream = ipfs.stats.bwReadableStream({ poll: true })

pull(
stream,
log()
)

// { totalIn: Big {...},
// totalOut: Big {...},
// rateIn: Big {...},
// rateOut: Big {...} }
// ...
// Ad infinitum
```

#### `bwReadableStream`

> Get IPFS bandwidth information as a [Readable Stream][rs].
##### `Go` **WIP**

##### `JavaScript` - ipfs.stats.bwReadableStream([options]) -> [Readable Stream][rs]

Options are described on [`ipfs.stats.bw`](#bw).

**Examples:**

```JavaScript
const stream = ipfs.stats.bwReadableStream({ poll: true })

stream.on('data', (data) => {
console.log(data)
}))

// { totalIn: Big {...},
// totalOut: Big {...},
// rateIn: Big {...},
// rateOut: Big {...} }
// ...
// Ad infinitum
```

[big]: https://github.com/MikeMcl/big.js/
[rs]: https://www.npmjs.com/package/readable-stream
[ps]: https://www.npmjs.com/package/pull-stream
20 changes: 5 additions & 15 deletions js/src/repo.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const statsTests = require('./utils/stats')
const expect = chai.expect
chai.use(dirtyChai)

Expand Down Expand Up @@ -46,26 +47,15 @@ module.exports = (common) => {
})

it('.stat', (done) => {
ipfs.repo.stat((err, stat) => {
expect(err).to.not.exist()
expect(stat).to.exist()
expect(stat).to.have.property('numObjects')
expect(stat).to.have.property('repoSize')
expect(stat).to.have.property('repoPath')
expect(stat).to.have.property('version')
expect(stat).to.have.property('storageMax')
ipfs.repo.stat((err, res) => {
statsTests.expectIsRepo(err, res)
done()
})
})

it('.stat Promise', () => {
return ipfs.repo.stat().then((stat) => {
expect(stat).to.exist()
expect(stat).to.have.property('numObjects')
expect(stat).to.have.property('repoSize')
expect(stat).to.have.property('repoPath')
expect(stat).to.have.property('version')
expect(stat).to.have.property('storageMax')
return ipfs.repo.stat().then((res) => {
statsTests.expectIsRepo(null, res)
})
})

Expand Down
85 changes: 40 additions & 45 deletions js/src/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const statsTests = require('./utils/stats')
const expect = chai.expect
const pull = require('pull-stream')
chai.use(dirtyChai)

module.exports = (common) => {
Expand Down Expand Up @@ -43,17 +45,7 @@ module.exports = (common) => {
}

ipfs.stats.bitswap((err, res) => {
expect(err).to.not.exist()
expect(res).to.exist()
expect(res).to.have.a.property('provideBufLen')
expect(res).to.have.a.property('wantlist')
expect(res).to.have.a.property('peers')
expect(res).to.have.a.property('blocksReceived')
expect(res).to.have.a.property('dataReceived')
expect(res).to.have.a.property('blocksSent')
expect(res).to.have.a.property('dataSent')
expect(res).to.have.a.property('dupBlksReceived')
expect(res).to.have.a.property('dupDataReceived')
statsTests.expectIsBitswap(err, res)
done()
})
})
Expand All @@ -65,16 +57,7 @@ module.exports = (common) => {
}

return ipfs.stats.bitswap().then((res) => {
expect(res).to.exist()
expect(res).to.have.a.property('provideBufLen')
expect(res).to.have.a.property('wantlist')
expect(res).to.have.a.property('peers')
expect(res).to.have.a.property('blocksReceived')
expect(res).to.have.a.property('dataReceived')
expect(res).to.have.a.property('blocksSent')
expect(res).to.have.a.property('dataSent')
expect(res).to.have.a.property('dupBlksReceived')
expect(res).to.have.a.property('dupDataReceived')
statsTests.expectIsBitswap(null, res)
})
})

Expand All @@ -85,12 +68,7 @@ module.exports = (common) => {
}

ipfs.stats.bw((err, res) => {
expect(err).to.not.exist()
expect(res).to.exist()
expect(res).to.have.a.property('totalIn')
expect(res).to.have.a.property('totalOut')
expect(res).to.have.a.property('rateIn')
expect(res).to.have.a.property('rateOut')
statsTests.expectIsBandwidth(err, res)
done()
})
})
Expand All @@ -102,28 +80,50 @@ module.exports = (common) => {
}

return ipfs.stats.bw().then((res) => {
expect(res).to.exist()
expect(res).to.have.a.property('totalIn')
expect(res).to.have.a.property('totalOut')
expect(res).to.have.a.property('rateIn')
expect(res).to.have.a.property('rateOut')
statsTests.expectIsBandwidth(null, res)
})
})

it('.bwReadableStream', (done) => {
if (!withGo) {
console.log('Not supported in js-ipfs yet')
return done()
}

const stream = ipfs.stats.bwReadableStream()

stream.once('data', (data) => {
statsTests.expectIsBandwidth(null, data)
stream.destroy()
done()
})
})

it('.bwPullStream', (done) => {
if (!withGo) {
console.log('Not supported in js-ipfs yet')
return done()
}

const stream = ipfs.stats.bwPullStream()

pull(
stream,
pull.collect((err, data) => {
statsTests.expectIsBandwidth(err, data[0])
done()
})
)
})

it('.repo', (done) => {
if (!withGo) {
console.log('Not supported in js-ipfs yet')
return done()
}

ipfs.stats.repo((err, res) => {
expect(err).to.not.exist()
expect(res).to.exist()
expect(res).to.have.a.property('numObjects')
expect(res).to.have.a.property('repoSize')
expect(res).to.have.a.property('repoPath')
expect(res).to.have.a.property('version')
expect(res).to.have.a.property('storageMax')
statsTests.expectIsRepo(err, res)
done()
})
})
Expand All @@ -135,12 +135,7 @@ module.exports = (common) => {
}

return ipfs.stats.repo().then((res) => {
expect(res).to.exist()
expect(res).to.have.a.property('numObjects')
expect(res).to.have.a.property('repoSize')
expect(res).to.have.a.property('repoPath')
expect(res).to.have.a.property('version')
expect(res).to.have.a.property('storageMax')
statsTests.expectIsRepo(null, res)
})
})
})
Expand Down
63 changes: 63 additions & 0 deletions js/src/utils/stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* eslint-env mocha */
/* eslint max-nested-callbacks: ["error", 8] */

'use strict'

const Big = require('big.js')
const { expect } = require('chai')

const isBigInt = (n) => {
return n.constructor.name === 'Big'
}

module.exports.expectIsBitswap = (err, stats) => {
expect(err).to.not.exist()
expect(stats).to.exist()
expect(stats).to.have.a.property('provideBufLen')
expect(stats).to.have.a.property('wantlist')
expect(stats).to.have.a.property('peers')
expect(stats).to.have.a.property('blocksReceived')
expect(stats).to.have.a.property('dataReceived')
expect(stats).to.have.a.property('blocksSent')
expect(stats).to.have.a.property('dataSent')
expect(stats).to.have.a.property('dupBlksReceived')
expect(stats).to.have.a.property('dupDataReceived')

expect(stats.provideBufLen).to.a('number')
expect(stats.wantlist).to.be.an('array')
expect(stats.peers).to.be.an('array')
expect(isBigInt(stats.blocksReceived)).to.eql(true)
expect(isBigInt(stats.dataReceived)).to.eql(true)
expect(isBigInt(stats.blocksSent)).to.eql(true)
expect(isBigInt(stats.dataSent)).to.eql(true)
expect(isBigInt(stats.dupBlksReceived)).to.eql(true)
expect(isBigInt(stats.dupDataReceived)).to.eql(true)
}

module.exports.expectIsBandwidth = (err, stats) => {
expect(err).to.not.exist()
expect(stats).to.exist()
expect(stats).to.have.a.property('totalIn')
expect(stats).to.have.a.property('totalOut')
expect(stats).to.have.a.property('rateIn')
expect(stats).to.have.a.property('rateOut')
expect(isBigInt(stats.totalIn)).to.eql(true)
expect(isBigInt(stats.totalOut)).to.eql(true)
expect(isBigInt(stats.rateIn)).to.eql(true)
expect(isBigInt(stats.rateOut)).to.eql(true)
}

module.exports.expectIsRepo = (err, res) => {
expect(err).to.not.exist()
expect(res).to.exist()
expect(res).to.have.a.property('numObjects')
expect(res).to.have.a.property('repoSize')
expect(res).to.have.a.property('repoPath')
expect(res).to.have.a.property('version')
expect(res).to.have.a.property('storageMax')
expect(isBigInt(res.numObjects)).to.eql(true)
expect(isBigInt(res.repoSize)).to.eql(true)
expect(isBigInt(res.storageMax)).to.eql(true)
expect(res.repoPath).to.be.a('string')
expect(res.version).to.be.a('string')
}
Loading

0 comments on commit 4421eb2

Please sign in to comment.