libp2p-kad-dht
Advanced tools
Comparing version 0.10.4 to 0.10.5
@@ -0,1 +1,11 @@ | ||
<a name="0.10.5"></a> | ||
## [0.10.5](https://github.com/libp2p/js-libp2p-kad-dht/compare/v0.10.4...v0.10.5) (2018-10-01) | ||
### Features | ||
* start random walk and allow configuration for disabling ([#42](https://github.com/libp2p/js-libp2p-kad-dht/issues/42)) ([abe9407](https://github.com/libp2p/js-libp2p-kad-dht/commit/abe9407)) | ||
<a name="0.10.4"></a> | ||
@@ -2,0 +12,0 @@ ## [0.10.4](https://github.com/libp2p/js-libp2p-kad-dht/compare/v0.10.3...v0.10.4) (2018-09-27) |
{ | ||
"name": "libp2p-kad-dht", | ||
"version": "0.10.4", | ||
"version": "0.10.5", | ||
"description": "JavaScript implementation of the Kad-DHT for libp2p", | ||
@@ -67,3 +67,3 @@ "leadMaintainer": "Vasco Santos <vasco.santos@moxy.studio>", | ||
"interface-connection": "~0.3.2", | ||
"libp2p-mplex": "~0.8.0", | ||
"libp2p-mplex": "~0.8.1", | ||
"libp2p-switch": "~0.40.5", | ||
@@ -74,3 +74,4 @@ "libp2p-tcp": "~0.12.0", | ||
"lodash.range": "^3.2.0", | ||
"peer-book": "~0.8.0" | ||
"peer-book": "~0.8.0", | ||
"sinon": "^6.3.4" | ||
}, | ||
@@ -77,0 +78,0 @@ "contributors": [ |
@@ -33,4 +33,7 @@ 'use strict' | ||
* | ||
* @param {Switch} sw | ||
* @param {object} options // {kBucketSize=20, datastore=MemoryDatastore} | ||
* @param {Switch} sw libp2p-switch instance | ||
* @param {object} options DHT options | ||
* @param {number} options.kBucketSize k-bucket size (default 20) | ||
* @param {Datastore} options.datastore datastore (default MemoryDatastore) | ||
* @param {boolean} options.enabledDiscovery enable dht discovery (default true) | ||
*/ | ||
@@ -100,2 +103,7 @@ constructor (sw, options) { | ||
this.randomWalk = new RandomWalk(this) | ||
/** | ||
* Random walk state, default true | ||
*/ | ||
this.randomWalkEnabled = !options.hasOwnProperty('enabledDiscovery') ? true : Boolean(options.enabledDiscovery) | ||
} | ||
@@ -120,3 +128,11 @@ | ||
this._running = true | ||
this.network.start(callback) | ||
this.network.start((err) => { | ||
if (err) { | ||
return callback(err) | ||
} | ||
// Start random walk if enabled | ||
this.randomWalkEnabled && this.randomWalk.start() | ||
callback() | ||
}) | ||
} | ||
@@ -133,5 +149,6 @@ | ||
this._running = false | ||
this.randomWalk.stop() | ||
this.providers.stop() | ||
this.network.stop(callback) | ||
this.randomWalk.stop(() => { // guarantee that random walk is stopped if it was started | ||
this.providers.stop() | ||
this.network.stop(callback) | ||
}) | ||
} | ||
@@ -138,0 +155,0 @@ |
@@ -16,3 +16,3 @@ 'use strict' | ||
assert(kadDHT, 'Random Walk needs an instance of the Kademlia DHT') | ||
this._running = false | ||
this._runningHandle = null | ||
this._kadDHT = kadDHT | ||
@@ -38,6 +38,36 @@ } | ||
this._running = setInterval( | ||
() => this._walk(queries, maxTimeout), | ||
period | ||
) | ||
// Create running handle | ||
const runningHandle = { | ||
_onCancel: null, | ||
_timeoutId: null, | ||
runPeriodically: (fn, period) => { | ||
runningHandle._timeoutId = setTimeout(() => { | ||
runningHandle._timeoutId = null | ||
fn((nextPeriod) => { | ||
// Was walk cancelled while fn was being called? | ||
if (runningHandle._onCancel) { | ||
return runningHandle._onCancel() | ||
} | ||
// Schedule next | ||
runningHandle.runPeriodically(fn, nextPeriod) | ||
}) | ||
}, period) | ||
}, | ||
cancel: (cb) => { | ||
// Not currently running, can callback immediately | ||
if (runningHandle._timeoutId) { | ||
clearTimeout(runningHandle._timeoutId) | ||
return cb() | ||
} | ||
// Wait to finish and then call callback | ||
runningHandle._onCancel = cb | ||
} | ||
} | ||
// Start runner | ||
runningHandle.runPeriodically((done) => { | ||
this._walk(queries, maxTimeout, () => done(period)) | ||
}, period) | ||
this._runningHandle = runningHandle | ||
} | ||
@@ -47,9 +77,15 @@ | ||
* Stop the random-walk process. | ||
* @param {function(Error)} callback | ||
* | ||
* @returns {void} | ||
*/ | ||
stop () { | ||
if (this._running) { | ||
clearInterval(this._running) | ||
stop (callback) { | ||
const runningHandle = this._runningHandle | ||
if (!runningHandle) { | ||
return callback() | ||
} | ||
this._runningHandle = null | ||
runningHandle.cancel(callback) | ||
} | ||
@@ -62,2 +98,3 @@ | ||
* @param {number} maxTimeout | ||
* @param {function(Error)} callback | ||
* @returns {void} | ||
@@ -67,3 +104,3 @@ * | ||
*/ | ||
_walk (queries, maxTimeout) { | ||
_walk (queries, maxTimeout, callback) { | ||
this._kadDHT._log('random-walk:start') | ||
@@ -78,5 +115,9 @@ | ||
], (err) => { | ||
if (err) { return this._kadDHT._log.error('random-walk:error', err) } | ||
if (err) { | ||
this._kadDHT._log.error('random-walk:error', err) | ||
return callback(err) | ||
} | ||
this._kadDHT._log('random-walk:done') | ||
callback(null) | ||
}) | ||
@@ -83,0 +124,0 @@ }) |
@@ -7,2 +7,3 @@ /* eslint-env mocha */ | ||
const expect = chai.expect | ||
const sinon = require('sinon') | ||
const series = require('async/series') | ||
@@ -73,3 +74,3 @@ const times = require('async/times') | ||
dhts.forEach((dht) => { | ||
dht.randomWalk._walk(3, 10000) | ||
dht.randomWalk._walk(3, 10000, () => {}) // don't need to know when it finishes | ||
}) | ||
@@ -140,2 +141,64 @@ } | ||
it('should be able to start and stop', function (done) { | ||
const sw = new Switch(peerInfos[0], new PeerBook()) | ||
sw.transport.add('tcp', new TCP()) | ||
sw.connection.addStreamMuxer(Mplex) | ||
sw.connection.reuse() | ||
const dht = new KadDHT(sw) | ||
sinon.spy(dht.network, 'start') | ||
sinon.spy(dht.randomWalk, 'start') | ||
sinon.spy(dht.network, 'stop') | ||
sinon.spy(dht.randomWalk, 'stop') | ||
series([ | ||
(cb) => dht.start(cb), | ||
(cb) => { | ||
expect(dht.network.start.calledOnce).to.equal(true) | ||
expect(dht.randomWalk.start.calledOnce).to.equal(true) | ||
cb() | ||
}, | ||
(cb) => dht.stop(cb) | ||
], (err) => { | ||
expect(err).to.not.exist() | ||
expect(dht.network.stop.calledOnce).to.equal(true) | ||
expect(dht.randomWalk.stop.calledOnce).to.equal(true) | ||
done() | ||
}) | ||
}) | ||
it('should be able to start with random-walk disabled', function (done) { | ||
const sw = new Switch(peerInfos[0], new PeerBook()) | ||
sw.transport.add('tcp', new TCP()) | ||
sw.connection.addStreamMuxer(Mplex) | ||
sw.connection.reuse() | ||
const dht = new KadDHT(sw, { enabledDiscovery: false }) | ||
sinon.spy(dht.network, 'start') | ||
sinon.spy(dht.randomWalk, 'start') | ||
sinon.spy(dht.network, 'stop') | ||
sinon.spy(dht.randomWalk, 'stop') | ||
series([ | ||
(cb) => dht.start(cb), | ||
(cb) => { | ||
expect(dht.network.start.calledOnce).to.equal(true) | ||
expect(dht.randomWalk.start.calledOnce).to.equal(false) | ||
cb() | ||
}, | ||
(cb) => dht.stop(cb) | ||
], (err) => { | ||
expect(err).to.not.exist() | ||
expect(dht.network.stop.calledOnce).to.equal(true) | ||
expect(dht.randomWalk.stop.calledOnce).to.equal(true) // Should be always disabled, as it can be started using the instance | ||
done() | ||
}) | ||
}) | ||
it('put - get', function (done) { | ||
@@ -212,3 +275,4 @@ this.timeout(10 * 1000) | ||
tdht.spawn(nDHTs, (err, dhts) => { | ||
// random walk disabled for a manual usage | ||
tdht.spawn(nDHTs, { enabledDiscovery: false }, (err, dhts) => { | ||
expect(err).to.not.exist() | ||
@@ -224,3 +288,2 @@ | ||
waitForWellFormedTables(dhts, 7, 0, 20 * 1000, cb) | ||
cb() | ||
} | ||
@@ -227,0 +290,0 @@ ], (err) => { |
@@ -21,4 +21,9 @@ 'use strict' | ||
spawn (n, callback) { | ||
times(n, (i, cb) => this._spawnOne(cb), (err, dhts) => { | ||
spawn (n, options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options | ||
options = {} | ||
} | ||
times(n, (i, cb) => this._spawnOne(options, cb), (err, dhts) => { | ||
if (err) { return callback(err) } | ||
@@ -29,3 +34,8 @@ callback(null, dhts) | ||
_spawnOne (callback) { | ||
_spawnOne (options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options | ||
options = {} | ||
} | ||
createPeerInfo(1, (err, peers) => { | ||
@@ -42,3 +52,3 @@ if (err) { return callback(err) } | ||
const dht = new KadDHT(sw) | ||
const dht = new KadDHT(sw, options) | ||
@@ -45,0 +55,0 @@ dht.validators.v = { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
154796
4899
13