From 6b07212f5dada2fa6728f59fbbf03a007983a5e8 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Tue, 14 May 2024 16:08:58 -0700 Subject: [PATCH 1/4] Send busy/idle at the right times Previously, busy/idle messages were sent for each output/effect. That isn't correct, those messages are only supposed to be sent when the session as a whole becomes busy/idle. --- shiny/express/_stub_session.py | 6 ++++++ shiny/reactive/_reactives.py | 4 ++-- shiny/session/_session.py | 27 +++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/shiny/express/_stub_session.py b/shiny/express/_stub_session.py index 19460cc10..7133bb915 100644 --- a/shiny/express/_stub_session.py +++ b/shiny/express/_stub_session.py @@ -119,6 +119,12 @@ async def _send_message(self, message: dict[str, object]) -> None: def _send_message_sync(self, message: dict[str, object]) -> None: return + def _increment_busy_count(self) -> None: + return + + def _decrement_busy_count(self) -> None: + return + def on_flush( self, fn: Callable[[], None] | Callable[[], Awaitable[None]], diff --git a/shiny/reactive/_reactives.py b/shiny/reactive/_reactives.py index a9147d91f..1503b42b2 100644 --- a/shiny/reactive/_reactives.py +++ b/shiny/reactive/_reactives.py @@ -547,7 +547,7 @@ def on_invalidate_cb() -> None: def _continue() -> None: ctx.add_pending_flush(self._priority) if self._session: - self._session._send_message_sync({"busy": "busy"}) + self._session._increment_busy_count() if self._suspended: self._on_resume = _continue @@ -558,7 +558,7 @@ async def on_flush_cb() -> None: if not self._destroyed: await self._run() if self._session: - self._session._send_message_sync({"busy": "idle"}) + self._session._decrement_busy_count() ctx.on_invalidate(on_invalidate_cb) ctx.on_flush(on_flush_cb) diff --git a/shiny/session/_session.py b/shiny/session/_session.py index 4be3962df..ff3880d76 100644 --- a/shiny/session/_session.py +++ b/shiny/session/_session.py @@ -471,6 +471,12 @@ def set_message_handler( namespaced when used with a session proxy. """ + @abstractmethod + def _increment_busy_count(self) -> None: ... + + @abstractmethod + def _decrement_busy_count(self) -> None: ... + # ====================================================================================== # AppSession @@ -493,6 +499,7 @@ def __init__( self.id: str = id self._conn: Connection = conn self._debug: bool = debug + self._busy_count: int = 0 self._message_handlers: dict[ str, tuple[Callable[..., Awaitable[Jsonifiable]], Session], @@ -785,11 +792,11 @@ async def uploadEnd(job_id: str, input_id: str) -> None: async def _handle_request( self, request: Request, action: str, subpath: Optional[str] ) -> ASGIApp: - self._send_message_sync({"busy": "busy"}) + self._increment_busy_count() try: return await self._handle_request_impl(request, action, subpath) finally: - self._send_message_sync({"busy": "idle"}) + self._decrement_busy_count() async def _handle_request_impl( self, request: Request, action: str, subpath: Optional[str] @@ -1011,6 +1018,16 @@ async def _flush(self) -> None: with session_context(self): await self._flushed_callbacks.invoke() + def _increment_busy_count(self) -> None: + self._busy_count += 1 + if self._busy_count == 1: + self._send_message_sync({"busy": "busy"}) + + def _decrement_busy_count(self) -> None: + self._busy_count -= 1 + if self._busy_count == 0: + self._send_message_sync({"busy": "idle"}) + # ========================================================================== # On session ended # ========================================================================== @@ -1191,6 +1208,12 @@ def _send_progress(self, type: str, message: object) -> None: async def send_custom_message(self, type: str, message: dict[str, object]) -> None: await self._parent.send_custom_message(type, message) + def _increment_busy_count(self) -> None: + self._parent._increment_busy_count() + + def _decrement_busy_count(self) -> None: + self._parent._decrement_busy_count() + def set_message_handler( self, name: str, From 73c73a1e7d4ee9221151f8baeaeec3f8efd863bb Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Tue, 14 May 2024 17:49:40 -0700 Subject: [PATCH 2/4] Fix unit test? --- tests/pytest/test_poll.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/pytest/test_poll.py b/tests/pytest/test_poll.py index 46b5b298c..1b876fae8 100644 --- a/tests/pytest/test_poll.py +++ b/tests/pytest/test_poll.py @@ -39,6 +39,12 @@ def on_ended(self, fn: Callable[[], None]) -> Callable[[], None]: def _send_message_sync(self, message: Dict[str, object]) -> None: pass + def _increment_busy_count(self) -> None: + pass + + def _decrement_busy_count(self) -> None: + pass + async def __aenter__(self): self._session_context.__enter__() From f4a9293f1dd5c08616db0ffc51cf4a1f55c6efca Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Wed, 15 May 2024 09:20:30 -0400 Subject: [PATCH 3/4] Bump example "time to init idle" timeout (which should never be reached) from 5s to 30s busy_indicator app takes minimum 4s to compute. Give a little bit extra time for CI to avoid adding a static wait time. --- tests/playwright/examples/example_apps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/examples/example_apps.py b/tests/playwright/examples/example_apps.py index 296c64f31..a5f0b54f0 100644 --- a/tests/playwright/examples/example_apps.py +++ b/tests/playwright/examples/example_apps.py @@ -33,7 +33,7 @@ def get_apps(path: str) -> typing.List[str]: return app_paths -app_idle_wait = {"duration": 300, "timeout": 5 * 1000} +app_idle_wait = {"duration": 300, "timeout": 30 * 1000} app_hard_wait: typing.Dict[str, int] = { "examples/brownian": 250, "examples/ui-func": 250, From 89f4078645b549780f08cc4fcb6ff34b710f89a1 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Wed, 15 May 2024 09:26:14 -0400 Subject: [PATCH 4/4] Add `ridgeplot` to testing dependencies --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 81cf1ce0f..2e4b31848 100644 --- a/setup.cfg +++ b/setup.cfg @@ -93,6 +93,7 @@ test = folium palmerpenguins faicons + ridgeplot dev = black>=24.0 flake8>=6.0.0