diff --git a/lib/Grape.js b/lib/Grape.js index cbd9422..fb54115 100644 --- a/lib/Grape.js +++ b/lib/Grape.js @@ -45,7 +45,8 @@ class Grape extends Events { host: this.conf.host || false, bootstrap: this.conf.dht_bootstrap, timeBucketOutdated: this.conf.dht_nodeLiveness, - verify: crypto.verify + verify: crypto.verify, + maxAge: this.conf.timeslot }) dht.on('announce', (_peer, ih) => { @@ -54,6 +55,12 @@ class Grape extends Events { this.emit('announce', val) }) + dht.on('unannounce', (_peer, ih) => { + const val = this.hex2str(ih) + debug(this.conf.dht_port, 'unannounce', val) + this.emit('unannounce', val) + }) + dht.on('warning', () => { debug(this.conf.dht_port, 'warning') this.emit('warning') @@ -128,15 +135,6 @@ class Grape extends Events { } } - timeslot (offset, ts) { - offset = offset || 0 - ts = ts || Date.now() - ts -= offset * this.conf.timeslot * -1 - ts = ts - (ts % this.conf.timeslot) - - return ts - } - onRequest (type, data, cb) { const met = `handlePeer${_.upperFirst(_.camelCase(`-${type}`))}` @@ -152,17 +150,10 @@ class Grape extends Events { return cb(new Error('ERR_GRAPE_LOOKUP')) } - async.reduce([ - `${_val}-${this.timeslot(0)}`, - `${_val}-${this.timeslot(-1)}` - ], [], (acc, slot, next) => { - this.lookup( - slot, - (err, res) => { - next(null, err ? acc : _.union(acc, res)) - } - ) - }, cb) + this.lookup( + _val, + cb + ) } handlePeerAnnounce (data, cb) { @@ -171,7 +162,16 @@ class Grape extends Events { } const [val, port] = [data[0], data[1]] - this.announce(`${val}-${this.timeslot(0)}`, port, cb) + this.announce(val, port, cb) + } + + handlePeerUnannounce (data, cb) { + if (!data || !_.isArray(data)) { + return cb(new Error('ERR_GRAPE_UNANNOUNCE')) + } + + const [val, port] = [data[0], data[1]] + this.unannounce(val, port, cb) } handlePeerPut (opts, cb) { @@ -209,6 +209,19 @@ class Grape extends Events { ) } + unannounce (val, port, cb) { + if (!_.isInteger(port)) { + return cb(new Error('ERR_GRAPE_SERVICE_PORT')) + } + + cb = cb || noop + this.node.unannounce( + this.str2hex(val), + port || this.conf.dht_port, + cb + ) + } + lookup (val, cb) { const ih = this.str2hex(val) @@ -219,6 +232,7 @@ class Grape extends Events { const kcnt = this.cbq0.cnt(ih) if (kcnt > 1) return + this._mem.remove(ih) this.node.lookup(ih, (err, cnt) => { debug(`lookup ${val} found ${cnt} nodes`) diff --git a/package.json b/package.json index cce5341..99435b0 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ ], "dependencies": { "async": "^2.6.0", - "bittorrent-dht": "^7.8.2", + "bittorrent-dht": "webtorrent/bittorrent-dht#unannounce", "cbq": "0.0.1", "debug": "^2.2.0", "ed25519-supercop": "^1.0.2", diff --git a/test/Grape.js b/test/Grape.js index 668eeaa..c0a7c1b 100644 --- a/test/Grape.js +++ b/test/Grape.js @@ -43,24 +43,6 @@ describe('Grape', () => { grape.stop(done) }) - it('timeslot returns the same for immediate calls', (done) => { - const grape = new Grape({ - dht_port: 20000, - api_port: 20001 - }) - - const now = Date.now() - - const ts1 = grape.timeslot(0, now) - const ts2 = grape.timeslot(0, now) - assert.equal(ts1, ts2) - - const ts3 = grape.timeslot(-1, now) - const ts4 = grape.timeslot(-1, now) - assert.equal(ts3, ts4) - done() - }) - it('requires a port', (done) => { const grape = new Grape({ dht_port: 20000