Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Commit

Permalink
refactor: callbacks -> async/await (#89)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: All places in the API that used callbacks are now replaced with async/await
  • Loading branch information
dirkmc authored and vasco-santos committed Jul 15, 2019
1 parent c51b0c8 commit 77cfc28
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 39 deletions.
10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,15 @@
"npm": ">=3.0.0"
},
"devDependencies": {
"aegir": "^18.2.1",
"chai": "^4.2.0",
"libp2p-tcp": "~0.13.0"
"aegir": "^20.0.0",
"chai": "^4.2.0"
},
"dependencies": {
"async": "^2.6.2",
"debug": "^4.1.1",
"mafmt": "^6.0.7",
"multiaddr": "^6.0.6",
"peer-id": "~0.12.2",
"peer-info": "~0.15.1"
"peer-id": "^0.13.2",
"peer-info": "^0.16.0"
},
"pre-push": [
"lint",
Expand Down
56 changes: 33 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,69 @@ const multiaddr = require('multiaddr')
const mafmt = require('mafmt')
const EventEmitter = require('events').EventEmitter
const debug = require('debug')
const nextTick = require('async/nextTick')

const log = debug('libp2p:bootstrap')
log.error = debug('libp2p:bootstrap:error')

function isIPFS (addr) {
try {
return mafmt.IPFS.matches(addr)
} catch (e) {
return false
}
}

/**
* Emits 'peer' events on a regular interval for each peer in the provided list.
*/
class Bootstrap extends EventEmitter {
/**
* Constructs a new Bootstrap.
*
* @param {Object} options
* @param {Array<string>} options.list - the list of peer addresses in multi-address format
* @param {number} options.interval - the interval between emitting addresses (in milli-seconds)
*
*/
constructor (options) {
super()
this._list = options.list
this._interval = options.interval || 10000
this._timer = null
}

start (callback) {
/**
* Start emitting events.
*/
start () {
if (this._timer) {
return nextTick(() => callback())
return
}

this._timer = setInterval(() => this._discoverBootstrapPeers(), this._interval)

nextTick(() => {
callback()
this._discoverBootstrapPeers()
})
this._discoverBootstrapPeers()
}

/**
* Emit each address in the list as a PeerInfo.
*/
_discoverBootstrapPeers () {
this._list.forEach((candidate) => {
if (!isIPFS(candidate)) { return log.error('Invalid multiaddr') }
this._list.forEach(async (candidate) => {
if (!mafmt.IPFS.matches(candidate)) {
return log.error('Invalid multiaddr')
}

const ma = multiaddr(candidate)

const peerId = PeerId.createFromB58String(ma.getPeerId())

PeerInfo.create(peerId, (err, peerInfo) => {
if (err) { return log.error('Invalid bootstrap peer id', err) }
try {
const peerInfo = await PeerInfo.create(peerId)
peerInfo.multiaddrs.add(ma)
this.emit('peer', peerInfo)
})
} catch (err) {
log.error('Invalid bootstrap peer id', err)
}
})
}

stop (callback) {
nextTick(callback)

/**
* Stop emitting events.
*/
stop () {
if (this._timer) {
clearInterval(this._timer)
this._timer = null
Expand Down
49 changes: 39 additions & 10 deletions test/bootstrap.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,61 @@ const { expect } = require('chai')
const mafmt = require('mafmt')

describe('bootstrap', () => {
it('find the other peer', function (done) {
it('find the other peer', function () {
this.timeout(5 * 1000)
const r = new Bootstrap({
list: peerList,
interval: 2000
})

r.once('peer', (peer) => done())
r.start(() => {})
const p = new Promise((resolve) => r.once('peer', resolve))
r.start()
return p
})

it('not fail on malformed peers in peer list', function (done) {
it('not fail on malformed peers in peer list', function () {
this.timeout(5 * 1000)

const r = new Bootstrap({
list: partialValidPeerList,
interval: 2000
})

r.start(() => { })
const p = new Promise((resolve) => {
r.once('peer', (peer) => {
const peerList = peer.multiaddrs.toArray()
expect(peerList.length).to.eq(1)
expect(mafmt.IPFS.matches(peerList[0].toString())).equals(true)
resolve()
})
})

r.start()

r.on('peer', (peer) => {
const peerList = peer.multiaddrs.toArray()
expect(peerList.length).to.eq(1)
expect(mafmt.IPFS.matches(peerList[0].toString()))
done()
return p
})

it('stop emitting events when stop() called', async function () {
const interval = 100
const r = new Bootstrap({
list: peerList,
interval
})

let emitted = []
r.on('peer', p => emitted.push(p))

// Should fire emit event for each peer in list on start,
// so wait 50 milliseconds then check
const p = new Promise((resolve) => setTimeout(resolve, 50))
r.start()
await p
expect(emitted).to.have.length(peerList.length)

// After stop is called, no more peers should be emitted
emitted = []
r.stop()
await new Promise((resolve) => setTimeout(resolve, interval))
expect(emitted).to.have.length(0)
})
})

0 comments on commit 77cfc28

Please sign in to comment.