From f4b74003c4d0257254a133f3d49e1cd25db04986 Mon Sep 17 00:00:00 2001 From: Buck Perley Date: Thu, 6 Jun 2019 16:10:09 -0500 Subject: [PATCH] indexer: add ability to track listeners and remove them on close for indexer --- lib/indexer/indexer.js | 19 +++++++++++++------ test/indexer-test.js | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/indexer/indexer.js b/lib/indexer/indexer.js index 33f45de9..3e1c6bc0 100644 --- a/lib/indexer/indexer.js +++ b/lib/indexer/indexer.js @@ -52,6 +52,7 @@ class Indexer extends EventEmitter { this.db = null; this.batch = null; + this.bound = []; this.syncing = false; this.height = 0; } @@ -122,12 +123,17 @@ class Indexer extends EventEmitter { } /** - * Close the indexer, wait for the database to close. + * Close the indexer, wait for the database to close, + * unbind all events. * @returns {Promise} */ async close() { - return this.db.close(); + await this.db.close(); + for (const [event, listener] of this.bound) + this.chain.removeListener(event, listener); + + this.bound.length = 0; } /** @@ -187,7 +193,7 @@ class Indexer extends EventEmitter { } /** - * Bind to chain events. + * Bind to chain events and save listeners for removal on close * @private */ @@ -202,9 +208,10 @@ class Indexer extends EventEmitter { } }; - this.chain.on('connect', listener); - this.chain.on('disconnect', listener); - this.chain.on('reset', listener); + for (const event of ['connect', 'disconnect', 'reset']) { + this.bound.push([event, listener]); + this.chain.on(event, listener); + } } /** diff --git a/test/indexer-test.js b/test/indexer-test.js index 53aada2b..7785057d 100644 --- a/test/indexer-test.js +++ b/test/indexer-test.js @@ -4,6 +4,7 @@ 'use strict'; const assert = require('bsert'); +const EventEmitter = require('events'); const reorg = require('./util/reorg'); const Script = require('../lib/script/script'); const Opcode = require('../lib/script/opcode'); @@ -320,6 +321,25 @@ describe('Indexer', function() { message: 'Limit above max of 10.' }); }); + + it('should track bound chain events and remove on close', async () => { + const indexer = new AddrIndexer({ + blocks: {}, + chain: new EventEmitter() + }); + + const events = ['connect', 'disconnect', 'reset']; + + await indexer.open(); + + for (const event of events) + assert.equal(indexer.chain.listeners(event).length, 1); + + await indexer.close(); + + for (const event of events) + assert.equal(indexer.chain.listeners(event).length, 0); + }); }); describe('Index 10 blocks', function() {