diff --git a/lib/index.js b/lib/index.js index bf57b87..b50f758 100644 --- a/lib/index.js +++ b/lib/index.js @@ -38,16 +38,6 @@ function assertGoalsPlugin(peer) { if (!peer.goals) throw new Error('gc plugin requires ppppp-goals plugin') } -/** - * @param {Config} config - * @returns {asserts config is ExpectedConfig} - */ -function assertValidConfig(config) { - if (typeof config.gc?.maxLogBytes !== 'number') { - throw new Error('gc requires config.gc.maxLogBytes') - } -} - /** * @param {{ db: PPPPPDB | null, goals: PPPPPGoal | null }} peer * @param {Config} config @@ -56,12 +46,6 @@ function initGC(peer, config) { // Assertions assertDBPlugin(peer) assertGoalsPlugin(peer) - assertValidConfig(config) - - const MAX_LOG_BYTES = config.gc.maxLogBytes - - /** Number of records that match roughly 1% of the max log size */ - const CHECKPOINT = Math.floor((MAX_LOG_BYTES * 0.01) / 500) // assuming 1 record = 500 bytes // State const debug = makeDebug('ppppp:gc') @@ -133,10 +117,11 @@ function initGC(peer, config) { /** * @param {number} percentUsed + * @param {number} maxLogBytes * @param {{ totalBytes: number; }} stats */ - function reportCleanupNeed(percentUsed, stats) { - const bytesRemaining = MAX_LOG_BYTES - stats.totalBytes + function reportCleanupNeed(percentUsed, maxLogBytes, stats) { + const bytesRemaining = maxLogBytes - stats.totalBytes const kbRemaining = bytesRemaining >> 10 const mbRemaining = bytesRemaining >> 20 const remaining = @@ -169,21 +154,27 @@ function initGC(peer, config) { /** * Monitor the log size and schedule compaction and/or cleanup. + * + * @param {number} maxLogBytes */ - function monitorLogSize() { + function monitorLogSize(maxLogBytes) { assertDBPlugin(peer) + + /** Number of records that match roughly 1% of the max log size */ + const CHECKPOINT = Math.floor((maxLogBytes * 0.01) / 500) // assuming 1 record = 500 bytes + function checkLogSize() { assertDBPlugin(peer) peer.db.log.stats((err, stats) => { if (err) return - const percentUsed = (stats.totalBytes / MAX_LOG_BYTES) * 100 + const percentUsed = (stats.totalBytes / maxLogBytes) * 100 const percentDeleted = (stats.deletedBytes / stats.totalBytes) * 100 const needsCleanup = percentUsed > 80 const needsCompaction = percentDeleted > 30 // Schedule clean up if ((needsCleanup || needsCompaction) && !hasCleanupScheduled) { - if (needsCleanup) reportCleanupNeed(percentUsed, stats) + if (needsCleanup) reportCleanupNeed(percentUsed, maxLogBytes, stats) if (needsCompaction) reportCompactionNeed(percentDeleted, stats) hasCleanupScheduled = true if (needsCleanup) { @@ -212,9 +203,15 @@ function initGC(peer, config) { checkLogSize() } - function start() { + /** + * @param {number?} maxLogBytes + */ + function start(maxLogBytes) { + const actualMaxLogBytes = maxLogBytes ?? config.gc?.maxLogBytes ?? null + // prettier-ignore + if (!actualMaxLogBytes) throw new Error('gc plugin requires maxLogBytes via start() argument or config.gc.maxLogBytes') if (!stopMonitoringLogSize) { - monitorLogSize() + monitorLogSize(actualMaxLogBytes) } } diff --git a/test/dict-ghosts.test.js b/test/dict-ghosts.test.js index bfd88fb..8995613 100644 --- a/test/dict-ghosts.test.js +++ b/test/dict-ghosts.test.js @@ -25,7 +25,6 @@ function isPresent(msg) { test('Dict ghosts', async (t) => { const alice = createPeer({ name: 'alice', - gc: { maxLogBytes: 100 * 1024 * 1024 }, dict: { ghostSpan: 2 }, }) diff --git a/test/feed-decay.test.js b/test/feed-decay.test.js index 6e3d410..d07dca7 100644 --- a/test/feed-decay.test.js +++ b/test/feed-decay.test.js @@ -10,7 +10,6 @@ function getTexts(msgs) { test('Feed decay', async (t) => { const alice = createPeer({ name: 'alice', - gc: { maxLogBytes: 100 * 1024 * 1024 }, }) await alice.db.loaded() diff --git a/test/feed-holes.test.js b/test/feed-holes.test.js index cf30bc6..7fef74c 100644 --- a/test/feed-holes.test.js +++ b/test/feed-holes.test.js @@ -10,7 +10,6 @@ function getTexts(msgs) { test('Feed holes', async (t) => { const alice = createPeer({ name: 'alice', - gc: { maxLogBytes: 100 * 1024 * 1024 }, }) await alice.db.loaded() diff --git a/test/orphan-weave.test.js b/test/orphan-weave.test.js index 489eef1..52ea5b2 100644 --- a/test/orphan-weave.test.js +++ b/test/orphan-weave.test.js @@ -14,7 +14,6 @@ function getTexts(msgs) { test('Orphan weave msgs', async (t) => { const alice = createPeer({ name: 'alice', - gc: { maxLogBytes: 100 * 1024 * 1024 }, }) await alice.db.loaded() diff --git a/test/schedule.test.js b/test/schedule.test.js index b1abcf9..88852be 100644 --- a/test/schedule.test.js +++ b/test/schedule.test.js @@ -8,11 +8,7 @@ function getTexts(msgs) { } test('Cleanup is scheduled automatically', async (t) => { - const alice = createPeer({ - name: 'alice', - gc: { maxLogBytes: 4 * 1024 }, // 4kB, approximately 8 messages - }) - + const alice = createPeer({ name: 'alice' }) await alice.db.loaded() // Alice creates her own account @@ -40,9 +36,8 @@ test('Cleanup is scheduled automatically', async (t) => { alice.goals.set(postFeedID, 'newest-3') assert('alice set a goal for newest-3 of post feed') - alice.gc.start() - - await p(setTimeout)(3000) + alice.gc.start(4 * 1024), // 4kB, approximately 8 messages + await p(setTimeout)(3000) assert.deepEqual( getTexts([...alice.db.msgs()]), @@ -54,11 +49,7 @@ test('Cleanup is scheduled automatically', async (t) => { }) test('Compaction is scheduled automatically', async (t) => { - const alice = createPeer({ - name: 'alice', - gc: { maxLogBytes: 6 * 1024 }, // 6kB, approximately 12 messages - }) - + const alice = createPeer({ name: 'alice' }) await alice.db.loaded() // Alice creates her own account @@ -101,7 +92,7 @@ test('Compaction is scheduled automatically', async (t) => { alice.goals.set(alice.db.feed.getID(aliceID, 'post3'), 'all') alice.goals.set(alice.db.feed.getID(aliceID, 'post4'), 'all') - alice.gc.start() + alice.gc.start(6 * 1024) // 6kB, approximately 12 messages await p(setTimeout)(3000)