From a3e9646046a45da7f5514a9b47aa33982230233c Mon Sep 17 00:00:00 2001 From: DougA Date: Wed, 14 Oct 2020 22:17:15 -0400 Subject: [PATCH 1/4] stress test --- test/stress.js | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/stress.js diff --git a/test/stress.js b/test/stress.js new file mode 100644 index 0000000..a4aab78 --- /dev/null +++ b/test/stress.js @@ -0,0 +1,51 @@ +/** + * Makes a couple dozen namespaced corestores + * Point is, every time a new corestore is made event listeners for 'feed' and 'error' are + * added but never removed unless the namespace is closed. + * + * emit 'feed' seems to be only needed for onready, + * if _unlisten is added after onready emits feed, this test passes + */ +const ram = require('random-access-memory') +const test = require('tape') +const Corestore = require('..') +const { once } = require('events') + +test('make a couple dozen namespaced corestores (without MaxListener warning)', async t => { + const store = await create(ram) + let spaces = [] + let cores = [] + + let index = 0 + while (index < 24) { + try { + spaces[index] = store.namespace('namespace-' + index) + cores[index] = spaces[index].default() + await cores[index].ready() + + t.ok(store.inner._events.feed.length < 3, '## feed event listener length before is only 1 or 2') + t.ok(spaces[index].inner._events.feed.length < 3, '## feed event listener length before is only 1 or 2') + t.ok(store.inner._events.error.length < 3, '## feed event listener length before is only 1 or 2') + t.ok(spaces[index].inner._events.error.length < 3, '## feed event listener length before is only 1 or 2') + + await once(store.inner, 'feed') + + t.ok(store.inner._events.feed === undefined, '## feed event listener length after is zero') + t.ok(spaces[index].inner._events.feed === undefined, '## feed event listener length after is zero') + t.ok(store.inner._events.error === undefined, '## feed event listener length after is zero') + t.ok(spaces[index].inner._events.error === undefined, '## feed event listener length after is zero') + } catch (err) { + console.error('error happened', err) + } + t.ok(store.inner._events.feed === undefined, 'no event listner memory leak') + index++ + } + + t.end() +}) + +async function create (storage, opts) { + const store = new Corestore(storage, opts) + await store.ready() + return store +} From 0b7d5265c60c220934f17cfbfdd23821baa8b37e Mon Sep 17 00:00:00 2001 From: DougA Date: Thu, 15 Oct 2020 07:38:10 -0400 Subject: [PATCH 2/4] add comments to stress test --- test/stress.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/stress.js b/test/stress.js index a4aab78..efc67aa 100644 --- a/test/stress.js +++ b/test/stress.js @@ -1,10 +1,13 @@ /** * Makes a couple dozen namespaced corestores - * Point is, every time a new corestore is made event listeners for 'feed' and 'error' are - * added but never removed unless the namespace is closed. - * - * emit 'feed' seems to be only needed for onready, - * if _unlisten is added after onready emits feed, this test passes + * + * For example, kappa-mulitfeed makes a new corestore for each new multifeed + * + * When more than 11 corestores are made, a MaxListenersExceededWarning happens + * due to too many listeners, see: + * + * https://github.com/andrewosh/corestore/issues/20 + * */ const ram = require('random-access-memory') const test = require('tape') @@ -23,6 +26,7 @@ test('make a couple dozen namespaced corestores (without MaxListener warning)', cores[index] = spaces[index].default() await cores[index].ready() + // feed and event never passes 3 listeners t.ok(store.inner._events.feed.length < 3, '## feed event listener length before is only 1 or 2') t.ok(spaces[index].inner._events.feed.length < 3, '## feed event listener length before is only 1 or 2') t.ok(store.inner._events.error.length < 3, '## feed event listener length before is only 1 or 2') @@ -30,6 +34,7 @@ test('make a couple dozen namespaced corestores (without MaxListener warning)', await once(store.inner, 'feed') + // feed and event never passes 0 listeners t.ok(store.inner._events.feed === undefined, '## feed event listener length after is zero') t.ok(spaces[index].inner._events.feed === undefined, '## feed event listener length after is zero') t.ok(store.inner._events.error === undefined, '## feed event listener length after is zero') From 9adf6b2107bb08d1a0a0fe4e5642055137fa1030 Mon Sep 17 00:00:00 2001 From: DougA Date: Thu, 15 Oct 2020 07:40:02 -0400 Subject: [PATCH 3/4] unlisten to events after feed emit --- index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 69aca7a..ba6ad00 100644 --- a/index.js +++ b/index.js @@ -319,7 +319,10 @@ class Corestore extends Nanoresource { this._isNamespaced = !!opts.name this._openedCores = new Map() - const onfeed = feed => this.emit('feed', feed) + const onfeed = feed => { + this.emit('feed', feed) + this._unlisten() + } const onerror = err => this.emit('error', err) this.inner.on('feed', onfeed) this.inner.on('error', onerror) From d7f893863401d14ceadabbc952618824af40dbb7 Mon Sep 17 00:00:00 2001 From: DougA Date: Thu, 15 Oct 2020 10:11:23 -0400 Subject: [PATCH 4/4] remove trailing spaces --- test/stress.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/stress.js b/test/stress.js index efc67aa..e2c7f39 100644 --- a/test/stress.js +++ b/test/stress.js @@ -1,13 +1,13 @@ /** * Makes a couple dozen namespaced corestores - * + * * For example, kappa-mulitfeed makes a new corestore for each new multifeed - * + * * When more than 11 corestores are made, a MaxListenersExceededWarning happens * due to too many listeners, see: - * + * * https://github.com/andrewosh/corestore/issues/20 - * + * */ const ram = require('random-access-memory') const test = require('tape')