feat(runtime): cell-level cached execution lifecycle#9895
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
No issues found across 16 files
Architecture diagram
sequenceDiagram
participant Frontend as Frontend (Browser)
participant Kernel as Kernel Runtime
participant RR as Runner/RunQueue
participant Sched as SequentialScheduler
participant Eval as Evaluator
participant CL as CachedLifecycle
participant Store as LazyStore (Cache)
participant SIG as SIGINT Handler
Note over Frontend,SIG: Cell-level Cached Execution Lifecycle
Frontend->>Kernel: Run cell(s) request
Kernel->>RR: run_all()
RR->>RR: Build Runner with CachedLifecycle (if cell_caching enabled)
RR->>Sched: async with scheduler (publishes to context)
Note over Sched,Kernel: Scheduler published as KernelRuntimeContext._active_scheduler
alt Cache MISS (first run or code changed)
RR->>Sched: pop_cell()
Sched-->>RR: cell_id
RR->>Eval: evaluate cell
Eval->>CL: setup(cell, glbls)
CL->>CL: hash cell + lookup cache
CL->>Store: Check cache key
Store-->>CL: MISS
Note over CL: Pre-flight check: any ref in glbls is UnhashableStub?
alt Stub found in refs
CL->>CL: Invalidate producer manifest
CL->>CL: Clear own attempt record
CL->>RR: raise MarimoCancelCellError(producers ∪ self)
RR->>Sched: requeue_for_rerun(producers ∪ cell)
Sched->>Sched: Topological sort, prepend to queue
Note over Sched: Producers run first next cycle
RR->>Eval: Skip cell execution this turn
else No stubs
CL-->>Eval: return None (run body)
Eval->>Eval: Execute cell body
Eval->>CL: teardown(cell, glbls, run_result)
CL->>CL: On success: save result to cache
CL->>Store: save_cache(attempt)
Store-->>CL: Saved
CL-->>Eval: Complete
Eval-->>RR: RunResult
end
else Cache HIT (same code, no UI elements restored)
RR->>Sched: pop_cell()
Sched-->>RR: cell_id
RR->>Eval: evaluate cell
Eval->>CL: setup(cell, glbls)
CL->>Store: Check cache key
Store-->>CL: HIT
CL->>CL: restore(glbls) from cache
alt Restored UI Element detected
Note over CL: UI elements need fresh session IDs
CL->>CL: Discard attempt, fall through to body execution
CL-->>Eval: return None (run body)
Eval->>Eval: Execute cell body
Eval->>CL: teardown (backfill cache)
else No UI elements
CL-->>Eval: return Skip(cached_result)
Note over Eval: Body short-circuited
Eval-->>RR: RunResult (from cache)
end
end
Note over Frontend,SIG: Updated SIGINT Routing
alt Async cell in flight (scheduler active tasks)
SIG->>SIG: Signal received
SIG->>SIG: Check active_scheduler via safe_get_context()
SIG->>Sched: has_active_tasks() = true
SIG->>Sched: cancel_all()
Sched->>Sched: Set interrupted flag
Sched->>Sched: call_soon_threadsafe(task.cancel) for each task
Note over SIG: Return without raising (avoids asyncio internals)
else Sync cell or between cells (scheduler active, no async tasks)
SIG->>SIG: Signal received
SIG->>SIG: Check active_scheduler via safe_get_context()
SIG->>Sched: has_active_tasks() = false
SIG->>Sched: cancel_all()
Sched->>Sched: Set interrupted flag
SIG->>Kernel: raise MarimoInterrupt (KeyboardInterrupt)
else No scheduler, no execution context
SIG->>SIG: Return silently
end
b0930ff to
5209b61
Compare
f0ff2e3 to
5cab29a
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new CachedLifecycle to enable cell-level cached execution within the runtime’s lifecycle framework, including a soft-cancel/requeue mechanism for stale “unhashable” placeholders and loader support for manifest-only markers when serialization fails.
Changes:
- Introduces
CachedLifecycleto restore cached defs/return values on hit and persist cache on successful miss. - Updates the lazy cache loader/schema to mark unserializable defs in the manifest (
unserializable_type) and reconstructUnhashableStubon load without writing blobs. - Extends the runner/scheduler to support soft-cancel requeue (
MarimoCancelCellError→requeue_for_rerun) and adds targeted test coverage.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/_save/stubs/test_unhashable_stub.py | Adds unit tests for UnhashableStub type name override + from_item reconstruction. |
| tests/_save/loaders/test_loader.py | Adds integration test ensuring unserializable defs write no blob and reload as UnhashableStub. |
| tests/_runtime/test_cached_stage.py | Adds runtime integration tests for cached lifecycle hit/miss and stub-driven requeue behavior. |
| marimo/_save/stubs/lazy_stub.py | Extends Item schema with unserializable_type; updates UnhashableStub to accept explicit type_name. |
| marimo/_save/loaders/lazy.py | Implements manifest-only marking on serialization failure; reconstructs UnhashableStub from manifest markers. |
| marimo/_runtime/runner/scheduler.py | Adds requeue_for_rerun to prepend cells in topological order for soft-cancel retries. |
| marimo/_runtime/runner/hook_context.py | Adds CancelledCells.discard() to “un-cancel” cells when requeued. |
| marimo/_runtime/runner/cell_runner.py | Wires CachedLifecycle via config and propagates/handles MarimoCancelCellError to requeue cells. |
| marimo/_runtime/executor/lifecycles/cached.py | New lifecycle implementing cache hit skip, miss persistence, and stub-ref preflight invalidation. |
da54d77 to
c872d31
Compare
aa9cebc to
1e5abde
Compare
6cb26c5 to
45fbfde
Compare
1e5abde to
325afe6
Compare
325afe6 to
073875f
Compare
073875f to
d7136ab
Compare
d7136ab to
3a0814e
Compare
d32f282 to
c156b9b
Compare
akshayka
left a comment
There was a problem hiding this comment.
This is much better, thank you. I liked the renamed exception. A couple of comments
91b3c07 to
113afa2
Compare
113afa2 to
2efe703
Compare
|
🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.14-dev9 |
Summary
This PR introduces the
CachedLifecyclewhich can be turned on via[marimo.tools.runtime.cache_cells].When the Lifecycle is active, all executed code is attempted to be cache. Stub hydration occurs when a cell must be executed. When stub hydration fails (e.g. an Unhashable stub), this code change allows for cell rescheduling, forcing a rerun.