Repository navigation
[LokiJS] Fix unsafeResetDatabase failing while an autosave is in progress - #8
Merged
Merged
Conversation
unsafeResetDatabase() closes Loki and then deletes the database. close() only waits for a save when Loki is dirty, but an autosave clears the dirty flags as soon as it starts. If one was still running, close() emitted 'close' synchronously and IncrementalIndexedDBAdapter.deleteDatabase threw "another operation is already in progress", rejecting the reset. Drain Loki's throttled save queue after close() and before deleting. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the fix addressing LokiJS database resets during in-progress saves.
No open issues 🎉
What changed in this PR
Fixes LokiJS unsafeResetDatabase() failing when an autosave is already in progress by waiting for pending saves before deleting the database.
Changes:
- Drains the throttled save queue after closing Loki, skips draining when throttling is disabled, and catches deletion errors.
- Adds a regression test using a persistence adapter that holds saves in progress.
- Documents the fix in the unreleased changelog.
| File | Description |
|---|---|
src/adapters/lokijs/worker/lokiExtensions.js |
Waits for pending saves before deletion and preserves error rejection. |
src/adapters/lokijs/test.js |
Tests resetting the database while a save is in progress. |
CHANGELOG-Unreleased.md |
Records the LokiJS reset fix. |
Review effort: Balanced
Author
|
Offered upstream as Nozbe#1980, rebuilt on upstream master. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
unsafeResetDatabase()on the LokiJS adapter callsdeleteDatabase(loki), which doesloki.close(() => loki.deleteDatabase(...)).close()only waits for a save if Loki is dirty. An autosave clears the dirty flags when it starts (ingetLokiCopy), so while one is in flight Loki looks clean.close()then emits'close'synchronously (Loki's listeners are synchronous), andIncrementalIndexedDBAdapter.deleteDatabasethrowsError while deleting database - another operation is already in progressbecauseoperationInProgressis still true. The throw comes out ofloki.close()inside the Promise executor, so the reset rejects.Fix
After
close(), wait for Loki's throttled save queue to drain (throttledSaveDrain) before callingdeleteDatabase. Two small guards:throttledSaveDraincalls its callback twice whenthrottledSavesis disabled (a lokijs bug: missingreturn), so the drain is skipped in that case.try/catchso it still rejects.Note: when a save is pending, Loki's drain runs one more save before calling back. That save finishes before the delete starts, so it's harmless.
Test
New Jest test in
src/adapters/lokijs/test.js. A fake incremental persistence adapter passed through_testLokiAdaptermimicsIncrementalIndexedDBAdapter: it throws on save/delete while another operation is in progress and can keep a save in flight. The test starts a save, callsunsafeResetDatabase(), checks that nothing is deleted while the save runs, then finishes the save and checks that the reset completes and the data is gone. Without the fix it fails with "another operation is already in progress".jest src/adapters/lokijs src/adapters/__tests__: 140 passedflow focus-checkon the changed file: cleanThis is independent of #7.
🤖 Generated with Claude Code