Skip to content
This repository has been archived by the owner on Mar 10, 2020. It is now read-only.

feat(breaking change): stats.bwReadableStream and stats.bwPullStream #211

Merged
merged 1 commit into from
Feb 7, 2018
Merged
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
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