Closed karangattu closed 4 months ago
What I'm seeing is that the .recalculating
class isn't being added to the plots on second render. This means the issue is likely less related directly to spinners and more to do with the output state machine.
If I manually add the .recalculating
class to any of the plots, e.g. #bars-plot
, the busy indicators appear as expected.
Repros for me too. Here's a deployment with just one plot: https://jcheng.shinyapps.io/busy_indicators/
The right events are coming across the wire, and no reason to believe they're not being handled correctly by the client. But the timing seems off. Like all the messages are being batched up for some reason.
Here's a Jam of just the refresh: https://jam.dev/c/92c69cc9-ac59-425e-9901-af540d2cf44d The messages all come in at the same time, after quite a delay.
And here's what the server logged:
2024-05-13T20:38:31.352585+00:00 shinyapps[11994497]: RECV: {"method":"update","data":{"rerender:bslib.taskbutton":{"value":1,"autoReset":true}}}
2024-05-13T20:38:31.356807+00:00 shinyapps[11994497]: SEND: {"progress": {"type": "binding", "message": {"id": "ring-plot"}}}
2024-05-13T20:38:31.360764+00:00 shinyapps[11994497]: SEND: {"busy": "busy"}
2024-05-13T20:38:31.364536+00:00 shinyapps[11994497]: SEND: {"recalculating": {"name": "ring-plot", "status": "recalculating"}}
2024-05-13T20:38:35.355109+00:00 shinyapps[11994497]: SEND: {"recalculating": {"name": "ring-plot", "status": "recalculated"}}
2024-05-13T20:38:35.359716+00:00 shinyapps[11994497]: SEND: {"busy": "idle"}
2024-05-13T20:38:35.363940+00:00 shinyapps[11994497]: SEND: {"values": {}, "inputMessages": [], "errors": {}}
2024-05-13T20:38:35.368323+00:00 shinyapps[11994497]: SEND: {"values": {"ring-plot": {"src": "data:image/png;[base64 data]", "width": "100%", "height": "100%", "coordmap": {"panels": [{"panel": 1, "row": 1, "col": 1, "domain": {"left": -4.95, "right": 103.95, "bottom": -3.6432772246667597, "top": 2.591291674972716}, "range": {"left": 90.4444444444444, "right": 3535.999999999999, "bottom": 1948.5555555555559, "top": 30.0}, "log": {"x": null, "y": null}, "mapping": {"x": null, "y": null}}], "dims": {"width": 3565.9999999999995, "height": 2026.0000000000002}}}}, "inputMessages": [{"id": "rerender", "message": {"state": "ready"}}], "errors": {}}
2024-05-13T20:38:35.372752+00:00 shinyapps[11994497]: SEND: {"progress": {"type": "binding", "message": {"id": "ring-plot"}}}
Note the 4-second delay between lines 4 and 5. (Also I'm not sure why the last line is another {progress: ...}
message, that seems like a stray one; that's the only time I saw that in my testing today and I wasn't able to get it to happen again)
@kippandrew Is there someone on your team that can work with us to figure out why this is happening? The timing of messages being sent back from shinyapps.io is quite different than what we're seeing on Connect, Shiny Server, and raw Shiny for Python--almost like proxied responses are being batched up or blocking on something. This is preventing progress indication from working.
Changing sockjs protocols doesn't fix it (I tried xhr-streaming and xhr-polling, both give the wrong behavior on shinyapps.io and both give the right behavior on Connect and SSOS).
Very surprising: no repro on a similar app written in R https://nafcillincat.shinyapps.io/shiny_busy_indicators_R/
@ssinnott figured out how to repro without shinyapps.io, if you pip install fastapi uvicorn websockets aiofiles starlette
you will get a repro locally. I'm still investigating why any of those matter.
Actually pip install fastapi
appears to be enough.
Alright, the problem is that fastapi
installs uvloop
which uvicorn will use if it's present. I'm not totally sure why this matters, maybe it has to do with run_coro_sync and/or run_coro_hybrid? :man_shrugging:
Here are two versions of a simple test app. The app-sync.py version repros the problem, the app-async.py version does not. The only difference is how they sleep--the sync version does a synchronous time.sleep(1)
while the async does await asyncio.sleep(1)
.
Maybe uvloop doesn't handle the task thread being blocked as well as asyncio does? I guess that would not be all that surprising given how async servers are usually implemented.
Ok should be fixed - my busy indicator application looks happier: https://ssinnott2.shinyapps.io/busy_indicators/
Since this was caused by adding fastapi
in the dependencies that ends up being baked into the image. So to "fix" an existing app you need to trigger a rebuild. The easiest route to do this is to either,
1) Deploy the application from the code again.
2) Archive -> unarchive the application in the shinyapps.io UI.
Excellent!! Thanks @ssinnott! https://www.youtube.com/watch?v=ouwPYxS_T2s
I ran the example app locally and all the spinners run during first load but also when I hit the
Re-render
button. When I deploy the same app to shinyapps.io, it shows all the spinners on first load, but does not show them when I hit theRe-render
plan. To make sure the requirements.txt file has the latest version of shiny, I modified therequirements.txt
file to look likeJam link with network and console tab - https://jam.dev/c/2cbd2d02-8a2f-4976-aa23-f56105fc2063