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

refactor: callbacks -> async/await #89

Merged
merged 8 commits into from
Jul 15, 2019
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
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 () {
dirkmc marked this conversation as resolved.
Show resolved Hide resolved
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)
})
})