Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ test =
folium
palmerpenguins
faicons
ridgeplot
dev =
black>=24.0
flake8>=6.0.0
Expand Down
6 changes: 6 additions & 0 deletions shiny/express/_stub_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]],
Expand Down
4 changes: 2 additions & 2 deletions shiny/reactive/_reactives.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
27 changes: 25 additions & 2 deletions shiny/session/_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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],
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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
# ==========================================================================
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion tests/playwright/examples/example_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 6 additions & 0 deletions tests/pytest/test_poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__()

Expand Down