Skip to content

fix(epoxy): reuse cached optimistic value#4618

Merged
MasterPtato merged 1 commit intomainfrom
04-12-fix_epoxy_reuse_cached_optimistic_value
Apr 13, 2026
Merged

fix(epoxy): reuse cached optimistic value#4618
MasterPtato merged 1 commit intomainfrom
04-12-fix_epoxy_reuse_cached_optimistic_value

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

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)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app
Copy link
Copy Markdown

railway-app bot commented Apr 13, 2026

🚅 Deployed to the rivet-pr-4618 environment in rivet-frontend

Service Status Web Updated (UTC)
kitchen-sink ❌ Build Failed (View Logs) Web Apr 13, 2026 at 7:36 pm
frontend-cloud ❌ Build Failed (View Logs) Web Apr 13, 2026 at 2:16 am
website ❌ Build Failed (View Logs) Web Apr 13, 2026 at 2:16 am
mcp-hub ✅ Success (View Logs) Web Apr 13, 2026 at 2:15 am
ladle ❌ Build Failed (View Logs) Web Apr 13, 2026 at 2:15 am
frontend-inspector ❌ Build Failed (View Logs) Web Apr 13, 2026 at 2:15 am

@claude
Copy link
Copy Markdown

claude bot commented Apr 13, 2026

PR Review: fix(epoxy): reuse cached optimistic value

Overall: Correct bug fix, clean implementation.

What This Fixes

The original code had a subtle but serious bug in the optimistic cache path of read_local_value. After deserializing the raw DB bytes into a CachedValue, it extracted the inner value: Vec<u8> field and then called cache_key.deserialize(&value)? on it again, treating the inner payload bytes as if they were a second serialized CachedValue blob.

This would fail at runtime for any non-empty cache entry, making the optimistic read path effectively broken.

The fix correctly reconstructs CachedValue by reusing the already-extracted bytes and reading cache_value.version directly.

Rust validity: the if let Some(value) = cache_value.value pattern partially moves cache_value.value out of the struct. Accessing cache_value.version afterward is valid because version is a separate field. The fields are spelled out explicitly with no struct update syntax (..cache_value).

Confirmed correct by tracing the consumer in get_optimistic.rs, which does local_read.cache_value.and_then(|v| v.value). The fix ensures v.value is Some(bytes) as expected.

Cargo.lock

The lock file reflects a version bump from 2.2.1 to 2.3.0-rc.4 across packages (epoxy, pegboard, gasoline, etc.) and new transitive deps: napi/napi-derive/napi-sys (Node.js native addon support) and libsqlite3-sys (native SQLite). These are unrelated to the bug fix and appear to come from base branch changes merged in.

Suggestions

Test coverage: No test exercises the include_cache=true path where the cache contains a non-empty value. Given this was a silent failure before, a regression test would be valuable: write a value via the fanout path (so it lands in cache but not committed storage), call read_local_value(..., include_cache=true), and assert cache_value.value is Some with the expected bytes.

Tombstone path: When cache_value deserializes with value: None, the code falls through and returns LocalValueRead { value: None, cache_value: None }. This is unchanged from before, but worth confirming the cache tombstone case is handled correctly upstream.

PR description: The draft template is unfilled. Worth adding a short motivation note before merging.

No other issues. The fix is minimal, correct, and easy to reason about.

@MasterPtato MasterPtato force-pushed the 04-12-fix_epoxy_reuse_cached_optimistic_value branch from 87ab8ab to c04f763 Compare April 13, 2026 19:35
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4618 April 13, 2026 19:35 Destroyed
Copy link
Copy Markdown
Contributor

MasterPtato commented Apr 13, 2026

Merge activity

  • Apr 13, 8:40 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Apr 13, 8:40 PM UTC: @MasterPtato merged this pull request with Graphite.

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