From 63a6d10f1ac74f86d257de410a4fcc067c137d9a Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 3 Jan 2019 14:17:40 +0000 Subject: [PATCH] fix: discover peers faster (#86) Previously we had to wait 10s (by default) **before** initial peer discovery, since the module uses an interval to re-emit discovered peers every 10s. This PR refactors `start` to do an initial discovery of the boostrap peers immediately after it has started (i.e. after the callback has been called). This addresses the problem where a call to `cat`/`get`/others immediately after the IPFS `ready` event would take at minimum 10s to get content stored on the preload nodes due to the initial delay in discovery. fixes #85 resolves https://github.com/ipfs/js-ipfs/issues/1706 License: MIT Signed-off-by: Alan Shaw --- src/index.js | 41 ++++++++++++++++++++++++----------------- test/bootstrap.spec.js | 6 +++--- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/index.js b/src/index.js index 9ebbff7..b692399 100644 --- a/src/index.js +++ b/src/index.js @@ -6,10 +6,10 @@ const multiaddr = require('multiaddr') const mafmt = require('mafmt') const EventEmitter = require('events').EventEmitter const debug = require('debug') -const setImmediate = require('async/setImmediate') +const nextTick = require('async/nextTick') -const log = debug('libp2p:railing') -log.error = debug('libp2p:railing:error') +const log = debug('libp2p:bootstrap') +log.error = debug('libp2p:bootstrap:error') function isIPFS (addr) { try { @@ -28,29 +28,36 @@ class Bootstrap extends EventEmitter { } start (callback) { - setImmediate(() => callback()) + if (this._timer) { + return nextTick(() => callback()) + } - if (this._timer) { return } + this._timer = setInterval(() => this._discoverBootstrapPeers(), this._interval) + + nextTick(() => { + callback() + this._discoverBootstrapPeers() + }) + } - this._timer = setInterval(() => { - this._list.forEach((candidate) => { - if (!isIPFS(candidate)) { return log.error('Invalid multiaddr') } + _discoverBootstrapPeers () { + this._list.forEach((candidate) => { + if (!isIPFS(candidate)) { return log.error('Invalid multiaddr') } - const ma = multiaddr(candidate) + const ma = multiaddr(candidate) - const peerId = PeerId.createFromB58String(ma.getPeerId()) + const peerId = PeerId.createFromB58String(ma.getPeerId()) - PeerInfo.create(peerId, (err, peerInfo) => { - if (err) { return log.error('Invalid bootstrap peer id', err) } - peerInfo.multiaddrs.add(ma) - this.emit('peer', peerInfo) - }) + PeerInfo.create(peerId, (err, peerInfo) => { + if (err) { return log.error('Invalid bootstrap peer id', err) } + peerInfo.multiaddrs.add(ma) + this.emit('peer', peerInfo) }) - }, this._interval) + }) } stop (callback) { - setImmediate(callback) + nextTick(callback) if (this._timer) { clearInterval(this._timer) diff --git a/test/bootstrap.spec.js b/test/bootstrap.spec.js index 5bf385c..c7397f8 100644 --- a/test/bootstrap.spec.js +++ b/test/bootstrap.spec.js @@ -1,7 +1,7 @@ /* eslint-env mocha */ 'use strict' -const Railing = require('../src') +const Bootstrap = require('../src') const peerList = require('./default-peers') const partialValidPeerList = require('./some-invalid-peers') const { expect } = require('chai') @@ -10,7 +10,7 @@ const mafmt = require('mafmt') describe('bootstrap', () => { it('find the other peer', function (done) { this.timeout(5 * 1000) - const r = new Railing({ + const r = new Bootstrap({ list: peerList, interval: 2000 }) @@ -22,7 +22,7 @@ describe('bootstrap', () => { it('not fail on malformed peers in peer list', function (done) { this.timeout(5 * 1000) - const r = new Railing({ + const r = new Bootstrap({ list: partialValidPeerList, interval: 2000 })