From 6663c9857d3144a08649e9b57da390df70a7cb29 Mon Sep 17 00:00:00 2001 From: Gregor MacLennan Date: Thu, 13 Jul 2023 12:32:42 +0100 Subject: [PATCH 1/2] breaking test for fd pool --- test/basic.js | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/test/basic.js b/test/basic.js index 10b0263..790271e 100644 --- a/test/basic.js +++ b/test/basic.js @@ -454,34 +454,36 @@ test('unlink on uncreated file does not reject', async function (t) { }) test('pool', function (t) { - t.plan(8) + const POOL_SIZE = 2 + const RAF_COUNT = 10 + + t.plan((RAF_COUNT * 2) + 2) - const pool = RAF.createPool(2) + const pool = RAF.createPool(POOL_SIZE) - const a = new RAF(gen(), { pool }) - const b = new RAF(gen(), { pool }) - const c = new RAF(gen(), { pool }) + const rafs = [] + let pending = RAF_COUNT + + for (let i = 0; i < RAF_COUNT; i++) { + const raf = new RAF(gen(), { pool }) + rafs.push(raf) + raf.write(0, Buffer.from('hello'), done) + } - a.write(0, Buffer.from('hello'), function (err) { + function done (err) { t.absent(err, 'no error') - b.write(0, Buffer.from('hello'), function (err) { - t.absent(err, 'no error') - c.write(0, Buffer.from('hello'), function (err) { - t.absent(err, 'no error') - setTimeout(function () { - t.is(pool.active.length, 2) - const all = [a, b, c] - t.is(all.filter(f => f.suspended).length, 1) - - for (const f of all) { - f.read(0, 5, function (_, buf) { - t.alike(buf, Buffer.from('hello')) - }) - } - }, 100) - }) - }) - }) + if (--pending !== 0) return + setTimeout(function () { + t.is(pool.active.length, POOL_SIZE) + t.is(rafs.filter(f => f.suspended).length, RAF_COUNT - POOL_SIZE) + + for (const f of rafs) { + f.read(0, 5, function (_, buf) { + t.alike(buf, Buffer.from('hello')) + }) + } + }, 100) + } }) test('readonly mode', function (t) { From 71c19fbec05513dd14022ad38df19af32101ed0b Mon Sep 17 00:00:00 2001 From: Gregor MacLennan Date: Thu, 13 Jul 2023 14:21:08 +0100 Subject: [PATCH 2/2] fix: alternative Pool implementation --- index.js | 20 ++++++++------------ test/basic.js | 2 +- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 4824381..b75fd4c 100644 --- a/index.js +++ b/index.js @@ -23,25 +23,21 @@ const CREAT = constants.O_CREAT class Pool { constructor (maxSize) { this.maxSize = maxSize - this.active = [] + this.active = new Set() } _onactive (file) { - // suspend a random one when the pool - if (this.active.length >= this.maxSize) { - const r = Math.floor(Math.random() * this.active.length) - this.active[r].suspend() + // suspend least recently inserted + if (this.active.size >= this.maxSize) { + const toSuspend = this.active[Symbol.iterator]().next().value + toSuspend.suspend() + this.active.delete(toSuspend) } - - file._pi = this.active.push(file) - 1 + this.active.add(file) } _oninactive (file) { - const head = this.active.pop() - if (head !== file) { - head._pi = file._pi - this.active[head._pi] = head - } + this.active.delete(file) } } diff --git a/test/basic.js b/test/basic.js index 790271e..00baa0a 100644 --- a/test/basic.js +++ b/test/basic.js @@ -474,7 +474,7 @@ test('pool', function (t) { t.absent(err, 'no error') if (--pending !== 0) return setTimeout(function () { - t.is(pool.active.length, POOL_SIZE) + t.is(pool.active.size, POOL_SIZE) t.is(rafs.filter(f => f.suspended).length, RAF_COUNT - POOL_SIZE) for (const f of rafs) {