Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocking tasks (sync or async) leads to ui frozen #1305

Open
mrdobalina2k opened this issue May 3, 2024 · 2 comments
Open

Blocking tasks (sync or async) leads to ui frozen #1305

mrdobalina2k opened this issue May 3, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@mrdobalina2k
Copy link

mrdobalina2k commented May 3, 2024

Describe the bug

Stacked UI elements are not updated when a task is running, which blocks the main thread. This is the case for both async and sync code. For example, I want to create a spinner that pops up conditionally when I press a button, and place that spinner in a stacked configuration. Instead of showing up, the stacked element greys out. I can see the other element where the spinner is created, that it pops up. For async this is not the case.

This occurs on other elements as well, for instance markdown elements.

Environment

{
"marimo": "0.4.10",
"OS": "Windows",
"OS Version": "11",
"Processor": "Intel64 Family 6 Model 126 Stepping 5, GenuineIntel",
"Python Version": "3.12.2",
"Binaries": {
"Browser": "123.0.6312.123",
"Node": "v14.16.0"
},
"Requirements": {
"click": "8.1.7",
"importlib-resources": "missing",
"jedi": "0.19.1",
"markdown": "3.6",
"pymdown-extensions": "10.7.1",
"pygments": "2.17.2",
"tomlkit": "0.12.4",
"uvicorn": "0.29.0",
"starlette": "0.37.2",
"websocket": "missing",
"typing-extensions": "4.9.0",
"black": "24.3.0"
}
}

Code to reproduce

import marimo
 
__generated_with = "0.4.10"
app = marimo.App()
 
 
@app.cell
def __():
    import marimo as mo
    import asyncio
    from time import sleep
    return asyncio, mo, sleep
 
 
@app.cell
def __(mo):
    get_do_something_async, set_do_something_async = mo.state(False)
    get_do_something_sync, set_do_something_sync = mo.state(False)
    return (
        get_do_something_async,
        get_do_something_sync,
        set_do_something_async,
        set_do_something_sync,
    )
 
 
@app.cell
def __(mo, set_do_something_async):
    button_do_async = mo.ui.button(label="Do something async", on_click=lambda v: set_do_something_async(True))
    return button_do_async,
 
 
@app.cell
def __(mo, set_do_something_sync):
    button_do_sync = mo.ui.button(label="Do something sync", on_click=lambda v: set_do_something_sync(True))
    return button_do_sync,
 
 
@app.cell
def __(get_do_something_async, mo):
    ui_do_async_spinner = mo.status.spinner(title="loading") if get_do_something_async() else mo.md("Waiting for async button press")
    ui_do_async_spinner
    return ui_do_async_spinner,
 
 
@app.cell
def __(get_do_something_sync, mo):
    ui_do_sync_spinner = mo.status.spinner(title="loading") if get_do_something_sync() else mo.md("Waiting for sync button press")
    ui_do_sync_spinner
    return ui_do_sync_spinner,
 
 
@app.cell
def __(get_do_something_sync, mo):
    ui_do_sync_pure_markdown = mo.md("""Running""") if get_do_something_sync() else mo.md("Waiting for sync button press")
    ui_do_sync_pure_markdown
    return ui_do_sync_pure_markdown,
 
 
@app.cell
async def __(asyncio, get_do_something_async, set_do_something_async):
    _trigger_async = get_do_something_async()
 
 
    async def do_something_async():
        await asyncio.sleep(5)
        print("Done")
 
    if _trigger_async:
        await do_something_async()
        set_do_something_async(False)
    return do_something_async,
 
 
@app.cell
def __(get_do_something_sync, set_do_something_sync, sleep):
    _trigger_sync = get_do_something_sync()
 
    def do_something_sync():
        sleep(5)
        print("Done")
 
    if _trigger_sync:
        do_something_sync()
        set_do_something_sync(False)
    return do_something_sync,
 
 
@app.cell
def __(button_do_sync, mo, ui_do_sync_spinner):
    mo.vstack([button_do_sync, ui_do_sync_spinner])
    return
 
 
@app.cell
def __(button_do_async, mo, ui_do_async_spinner):
    mo.vstack([button_do_async, ui_do_async_spinner])
    return
 
 
@app.cell
def __(button_do_sync, mo, ui_do_sync_pure_markdown):
    mo.vstack([button_do_sync, ui_do_sync_pure_markdown])
    return
 
 
if __name__ == "__main__":
    app.run()
@mrdobalina2k mrdobalina2k added the bug Something isn't working label May 3, 2024
@mscolnick
Copy link
Contributor

mscolnick commented May 3, 2024

I'm not 100% sure i follow the use case - i'll try to digest it more. But in the meantime, have you see the mo.output.replace/mo.output.append/mo.output.clear? The allow you to update the cell output (replace/append/clear) before the cell finished.

e.g.

mo.output.replace(mo.status.spinner(title="loading"))

# do things

mo.ouput.replace(mo.md("First result: ", result)

# do more things

result

https://docs.marimo.io/api/outputs.html#cell-outputs

@mrdobalina2k
Copy link
Author

It's related to the example given in #1271,
This works when the action (clicking a button), is inexpensive. However, in my use case I am calling a calculation engine, which takes seconds to return the results. Instead of showing the spinner, it doesn't show up and once the output returns it is gone. I'll take a look at the mo.output, maybe that's what I need..

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

No branches or pull requests

2 participants