Skip to content

fix: make threads share their accumulated output#8418

Merged
akshayka merged 11 commits intomainfrom
aka/threadsafe-cell-output-list
Feb 22, 2026
Merged

fix: make threads share their accumulated output#8418
akshayka merged 11 commits intomainfrom
aka/threadsafe-cell-output-list

Conversation

@akshayka
Copy link
Contributor

This PR makes mo.Threads share their creating cell's accumulated output list. This improves the experience of imperatively writing output with threads in two ways:

  1. Multiple threads can now write to the output, without overwriting each other's outputs
  2. Thread outputs are no longer automatically cleared when the spawning cell completes

To accommodate this, this PR abstracts away the underlying list of imperative outputs, and instead introduces a thread-safe container that manages access to the outputs data structure.

This change also makes mo.status.progress_bar thread-safe.

Follow up to #8413

Represent empty output as an empty list, and never the object
bound to it; child threads need to share the parent thread's
output object, which is not possible if mo.output* methods
set it to None.
@akshayka akshayka requested a review from dmadisetti as a code owner February 21, 2026 20:15
@vercel
Copy link

vercel bot commented Feb 21, 2026

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

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Feb 21, 2026 8:30pm

Request Review

@akshayka akshayka added the bug Something isn't working label Feb 21, 2026
Copy link
Contributor

Copilot AI left a comment

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 updates marimo’s imperative output plumbing so mo.Thread instances share the spawning cell’s accumulated output container, enabling safe multi-thread appends and preventing thread output from being wiped when the parent cell completes. It also adds thread-safety to mo.status.progress_bar updates.

Changes:

  • Introduce CellOutputList, a thread-safe container for imperative cell outputs, and make it the default for ExecutionContext.output.
  • Update mo.output.* internals, kernel output caching, and post-exec output broadcast logic to work with CellOutputList.
  • Make progress bar updates thread-safe and add runtime + smoke tests covering threaded output scenarios.

Reviewed changes

Copilot reviewed 12 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/_runtime/test_threads.py Adds coverage ensuring threads share the parent cell’s output container.
tests/_runtime/test_cell_output_list.py Adds unit tests for CellOutputList behavior.
marimo/_smoke_tests/threads/threads.py Smoke test for stdout redirection with threading.Thread vs mo.Thread.
marimo/_smoke_tests/threads/state_threading.py Smoke test exercising state updates from a background mo.Thread.
marimo/_smoke_tests/threads/progress_bar_threads.py Smoke test for progress bar updates from multiple threads.
marimo/_smoke_tests/threads/multiple_appends.py Smoke test for concurrent append/replace output patterns with threads.
marimo/_smoke_tests/status/status.py Adds status component smoke coverage (progress bars/spinners).
marimo/_smoke_tests/output.py Updates output smoke test formatting + includes replace-at-index usage.
marimo/_runtime/threads.py Shares parent ExecutionContext.output into thread execution contexts.
marimo/_runtime/runner/hooks_post_execution.py Adjusts output broadcast condition to use CellOutputList truthiness.
marimo/_runtime/output/_output.py Refactors imperative output ops to use CellOutputList methods and stack().
marimo/_runtime/context/types.py Makes ExecutionContext.output a non-optional CellOutputList via default_factory.
marimo/_runtime/cell_output_list.py New thread-safe output container implementation.
marimo/_runtime/app/kernel_runner.py Updates cached-output handling to stack CellOutputList.
marimo/_plugins/stateless/status/_progress.py Adds locking around progress updates for thread-safety.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

akshayka and others added 2 commits February 21, 2026 12:28
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@akshayka
Copy link
Contributor Author

@coastalwhite this should generally improve your experience of writing to output from multiple threads (including with progress bars)

image
@akshayka akshayka requested a review from dmadisetti February 21, 2026 20:33
@akshayka akshayka merged commit 71e8b8e into main Feb 22, 2026
42 of 43 checks passed
@akshayka akshayka deleted the aka/threadsafe-cell-output-list branch February 22, 2026 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

2 participants