diff --git a/lib/log/index.js b/lib/log/index.js index 8e8ae4e..4c0d04c 100644 --- a/lib/log/index.js +++ b/lib/log/index.js @@ -634,6 +634,11 @@ function Log(filename, opts) { * @param {CB} cb */ function overwrite(offset, data, cb) { + if (compacting) { + waitingCompaction.push(() => overwrite(offset, data, cb)) + return + } + let encodedData = codec.encode(data) if (typeof encodedData === 'string') encodedData = b4a.from(encodedData) @@ -707,10 +712,6 @@ function Log(filename, opts) { * @param {CB?} cb */ async function compact(cb) { - if (compacting) { - if (cb) waitingCompaction.push(cb) - return - } cb ??= logError const debug2 = debug.extend('compact') if (deletedBytes === 0) { @@ -724,9 +725,13 @@ function Log(filename, opts) { // prettier-ignore return cb(new Error('Compact failed to pre-flush overwrites', { cause: err1 })) } + if (compacting) { + if (cb) waitingCompaction.push(cb) + return + } + compacting = true const startCompactTimestamp = Date.now() - compacting = true if (compactionProgress.value.done) { compactionProgress.set(COMPACTION_PROGRESS_START) } @@ -734,6 +739,7 @@ function Log(filename, opts) { const filenameNew = filename + '.compacting' const [err2] = await p(fs.unlink.bind(fs))(filenameNew) if (err2 && err2.code !== 'ENOENT') { + compacting = false // prettier-ignore return cb(new Error('Compact failed to get rid of previous compacting log', { cause: err2 })) } @@ -846,15 +852,16 @@ function Log(filename, opts) { const nextSince = latestBlockIndex * blockSize + nextOffsetInBlock const sizeDiff = oldTotalBytes - getTotalBytes() lastRecOffset.set(nextSince) - compacting = false const duration = Date.now() - startCompactTimestamp debug2('Completed in %d ms', duration) deletedBytes = 0 const [err7] = await p(saveStats)() if (err7) { + compacting = false return cb(new Error('Compact failed to save stats file', { cause: err7 })) } compactionProgress.set({ percent: 1, done: true, sizeDiff, holesFound }) + compacting = false for (const callback of waitingCompaction) callback() waitingCompaction.length = 0 cb() diff --git a/test/log/compact.test.js b/test/log/compact.test.js index aa32ce9..4f2f364 100644 --- a/test/log/compact.test.js +++ b/test/log/compact.test.js @@ -30,7 +30,6 @@ test('Log compaction', async (t) => { }) await p(log.compact)() - await p(log.onDrain)() assert.deepEqual( progressArr, @@ -88,7 +87,6 @@ test('Log compaction', async (t) => { assert('delete first record') await p(log.compact)() - await p(log.onDrain)() assert.deepEqual( progressArr, @@ -153,7 +151,6 @@ test('Log compaction', async (t) => { }) await p(log.compact)() - await p(log.onDrain)() await new Promise((resolve, reject) => { const arr = []