Skip to content

fix: Cache.load() leaving partial state after WAL replay failure - #342

Merged
mattsva merged 1 commit into
danieldeer:mainfrom
TynK-M:main
Oct 12, 2026
Merged

mattsva merged 1 commit into
danieldeer:mainfrom
TynK-M:main

Conversation

@TynK-M

@TynK-M TynK-M commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Description

This PR makes Cache.load() failure-atomic by loading the database snapshot and replaying WAL entries into temporary state before updating the cache instance.

Previously, if WAL replay raised an OSError, the cache could retain partially initialized attributes, potentially causing subsequent operations to behave incorrectly.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Key Changes

  • Load the snapshot and replay WAL entries before committing state to the cache.
  • Update cache attributes only after loading and replay succeed.
  • Add a regression test verifying that a failed load leaves the cache uninitialized.
  • Verify that retrying the load recovers committed WAL entries and that the entries survive subsequent compaction.

Validation

I used the pre-commit CI already existing the repository, also using the updated tests.

Checklist

  • I reviewed the diff and kept it focused on the described change.
  • Python changes pass uv run ruff check . and uv run ruff format --check ., or this PR does not change Python.
  • Changed behavior is covered by appropriate tests, including a regression test for bug fixes; any limitations are explained under Validation.
  • Validation lists the checks or manual flows I ran and their results.
  • Relevant documentation is updated, or no documentation change is needed.

Loads the snapshot and replay WAL entries into temporary state before
updating the cache attributes. This prevent WAL replay failures from
leaving the cache partially initialized.

Adds a regression test verifying that failed loads leave the cache
uninitialized and that commited WAL entries survive retry and subsequent
compaction.
@TynK-M TynK-M changed the title Fix Cache.load() leaving partial state after WAL replay failure fix: Cache.load() leaving partial state after WAL replay failure Oct 12, 2026
@TynK-M

TynK-M commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

@mattsva, here’s the PR that closes issue #341. I’d be happy to have you review it.

@mattsva mattsva left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good to me! Ive tested it locally using Nix-shell and a few self-made test scripts. I also tested a few potential edge cases related to this fix and couldnt reproduce any further issues.
This fixes #341. Good job, @TynK-M!

@mattsva

mattsva commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Merging this.

@mattsva
mattsva merged commit 9e99460 into danieldeer:main Oct 12, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants