Skip to content

fix: increased cache robustness for wire level cell resolution#10109

Merged
dmadisetti merged 1 commit into
mainfrom
dm/cache-robustness
Jul 8, 2026
Merged

fix: increased cache robustness for wire level cell resolution#10109
dmadisetti merged 1 commit into
mainfrom
dm/cache-robustness

Conversation

@dmadisetti

@dmadisetti dmadisetti commented Jul 8, 2026

Copy link
Copy Markdown
Member

📝 Summary

This PR resolves 3 issues with the cell level caching introduced.

  1. @mo.persistent_cache functions were not correctly resolved and their subsequent calling would break if dependent on a unhashable stub
  2. The stubbing mechanism frequently failed because unhashable stubs could not be resolved to compute downstream hashes. This PR introduces a change to include the runtime stub into the saved format, unlocking downstream hash computation.
  3. The kernel can exit and finish before the background cache is fully done processing. Kernel hooks are already known surface area, this allows for hooks to be called after the kernel has run. This in turn is used to flush the cache to ensure export consistency.

Copilot AI review requested due to automatic review settings July 8, 2026 19:33
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Jul 8, 2026 8:28pm

Request Review

@dmadisetti dmadisetti added the bug Something isn't working label Jul 8, 2026
@dmadisetti
dmadisetti force-pushed the dm/cache-robustness branch from 6450f9d to 32b44cb Compare July 8, 2026 19:42
dmadisetti added a commit that referenced this pull request Jul 8, 2026
Bundle a session's per-cell and per-function caches into the output of
marimo export html-wasm --execute, so a dependency-free browser (Pyodide)
can skip recomputation. Stacked on the cache-robustness PR (#10109), which
provides the graceful-degrade / hashing-parity restore machinery this relies
on to consume the bundled caches without the original deps.

This pull request was authored by a coding agent.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR bumps the persistent cache schema to v5 and hardens cell-level caching in environments where optional dependencies (e.g. torch in WASM) are unavailable, while also ensuring background cache writes are flushed during kernel teardown for export/durability consistency.

Changes:

  • Improve stub/restore behavior so unmaterializable defs (missing optional deps) still allow downstream cache-key reproduction via persisted content digests, and cached wrappers (@mo.cache / @mo.persistent_cache) can be reconstituted as working wrappers on restore.
  • Avoid fetching blobs that can’t be deserialized in the current environment (root module absent), substituting an UnhashableStub that carries the persisted digest.
  • Add teardown-time flushing for lazy loader background writes and adjust invalidation semantics to mark manifests stale (without destroying recoverable cache entries).

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/_save/stubs/test_module_stub.py Adds coverage for ModuleStub version fallback to root package version and empty-version behavior.
tests/_save/loaders/test_loader.py Adds coverage ensuring absent-module blobs are not fetched and content digests propagate into stubs.
tests/_runtime/test_cached_stage.py Updates invalidation expectations (stale-only) and adds scenario coverage for serializable siblings not forcing live reruns.
marimo/_session/managers/kernel.py Attempts cleaner shutdown and gives the kernel time to flush pending work before termination.
marimo/_save/stubs/module_stub.py Captures root package __version__ for submodule aliases to preserve version-pinned hashes on restore.
marimo/_save/stubs/lazy_stub.py Extends schema (function tuples) and enriches UnhashableStub with content_hash for downstream hashing.
marimo/_save/stubs/function_stub.py Adds cached-wrapper support (is_cached) and dump/restore helpers for schema persistence.
marimo/_save/loaders/loader.py Introduces a flush() hook for loaders to drain async writes.
marimo/_save/loaders/lazy.py Adds module-availability gating for blob fetch, persists content digests, and wires in global flush for active loaders.
marimo/_save/loaders/init.py Exposes flush_active_caches from loaders package.
marimo/_save/hash.py Teaches the hasher to replay persisted content digests from restored stubs and to handle marimo-owned stubs without flipping cache mode.
marimo/_save/cache.py Bumps cache version to 5; improves restore degradation behavior and adds cached-wrapper stub capture/restore logic.
marimo/_runtime/runtime.py Adds callback teardown phase while runtime context is still alive.
marimo/_runtime/kernel_lifecycle.py Invokes callback teardown before tearing down runtime context.
marimo/_runtime/executor/lifecycles/cached.py Improves logging/UI def detection and changes invalidation to stale-only (no clear).
marimo/_runtime/callbacks/protocol.py Adds SupportsTeardown runtime-checkable protocol.
marimo/_runtime/callbacks/cache.py Implements teardown flush of active caches for durability on kernel teardown.
marimo/_runtime/callbacks/init.py Re-exports SupportsTeardown.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread marimo/_save/stubs/function_stub.py
Comment thread marimo/_save/cache.py
Comment thread marimo/_save/hash.py
Comment thread marimo/_save/stubs/lazy_stub.py
@dmadisetti
dmadisetti force-pushed the dm/cache-robustness branch from 32b44cb to 72f09a2 Compare July 8, 2026 20:27
dmadisetti added a commit that referenced this pull request Jul 8, 2026
Bundle a session's per-cell and per-function caches into the output of
marimo export html-wasm --execute, so a dependency-free browser (Pyodide)
can skip recomputation. Stacked on the cache-robustness PR (#10109), which
provides the graceful-degrade / hashing-parity restore machinery this relies
on to consume the bundled caches without the original deps.

This pull request was authored by a coding agent.
@mscolnick
mscolnick requested a review from Copilot July 8, 2026 22:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment on lines +19 to +23
def __init__(self, function: Any, is_cached: bool = False) -> None:
self.is_cached = is_cached
if is_cached:
# Capture the wrapped body's source (incl. the decorator line).
function = function.__wrapped__

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think anyone has FunctionStub pickles yet, so this is fine. Technically breaking but I expect 0 impact

Comment thread marimo/_save/loaders/lazy.py
@dmadisetti dmadisetti changed the title fix(cache v5): increased cache robustness for wire level cell resolution fix: increased cache robustness for wire level cell resolution Jul 8, 2026
if var not in variable_hashes:
# NB. persist a digest for data primitives so a consumer
# reproduces its key without the value.
digest = _maybe_content_digest(obj)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should this happen in a thread? is this expensive to do on the main thread and in a for loop

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good point. will be care for when this runs through WASM. Doing this as a follow up to unblock my other branch in the meantime

@mscolnick mscolnick left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks great! one small comment on perf for the lazy store

@dmadisetti
dmadisetti merged commit b8b4ebb into main Jul 8, 2026
45 checks passed
@dmadisetti
dmadisetti deleted the dm/cache-robustness branch July 8, 2026 23:08
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.14-dev37

dmadisetti added a commit that referenced this pull request Jul 8, 2026
Bundle a session's per-cell and per-function caches into the output of
marimo export html-wasm --execute, so a dependency-free browser (Pyodide)
can skip recomputation. Stacked on the cache-robustness PR (#10109), which
provides the graceful-degrade / hashing-parity restore machinery this relies
on to consume the bundled caches without the original deps.

This pull request was authored by a coding agent.
dmadisetti added a commit that referenced this pull request Jul 9, 2026
Bundle a session's per-cell and per-function caches into the output of
marimo export html-wasm --execute, so a dependency-free browser (Pyodide)
can skip recomputation. Stacked on the cache-robustness PR (#10109), which
provides the graceful-degrade / hashing-parity restore machinery this relies
on to consume the bundled caches without the original deps.

This pull request was authored by a coding agent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants