Skip to content

Commit

Permalink
use background task to cancel content deletion on handshake
Browse files Browse the repository at this point in the history
  • Loading branch information
falkoschindler committed Jan 29, 2025
1 parent d73370c commit b4916b9
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 8 deletions.
4 changes: 2 additions & 2 deletions nicegui/air.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ def _handle_handshake(data: Dict[str, Any]) -> bool:
return True

@self.relay.on('client_disconnect')
async def _handle_client_disconnect(data: Dict[str, Any]) -> None:
def _handle_client_disconnect(data: Dict[str, Any]) -> None:
self.log.debug('client disconnected.')
client_id = data['client_id']
if client_id not in Client.instances:
return
await Client.instances[client_id].handle_disconnect()
Client.instances[client_id].handle_disconnect()

@self.relay.on('connect')
async def _handle_connect() -> None:
Expand Down
15 changes: 11 additions & 4 deletions nicegui/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def __init__(self, page: page, *, request: Optional[Request]) -> None:
self.shared = request is None
self.on_air = False
self._num_connections = 0
self._delete_task: Optional[asyncio.Task] = None
self._deleted = False
self.tab_id: Optional[str] = None

Expand Down Expand Up @@ -236,6 +237,9 @@ def on_disconnect(self, handler: Union[Callable[..., Any], Awaitable]) -> None:

def handle_handshake(self, next_message_id: Optional[int]) -> None:
"""Cancel pending disconnect task and invoke connect handlers."""
if self._delete_task:
self._delete_task.cancel()
self._delete_task = None
self._num_connections += 1
if next_message_id is not None:
self.outbox.try_rewind(next_message_id)
Expand All @@ -245,16 +249,19 @@ def handle_handshake(self, next_message_id: Optional[int]) -> None:
for t in core.app._connect_handlers: # pylint: disable=protected-access
self.safe_invoke(t)

async def handle_disconnect(self) -> None:
def handle_disconnect(self) -> None:
"""Wait for the browser to reconnect; invoke disconnect handlers if it doesn't."""
async def delete_content() -> None:
await asyncio.sleep(self.page.resolve_reconnect_timeout())
if self._num_connections == 0:
self.delete()
self._num_connections -= 1
for t in self.disconnect_handlers:
self.safe_invoke(t)
for t in core.app._disconnect_handlers: # pylint: disable=protected-access
self.safe_invoke(t)
await asyncio.sleep(self.page.resolve_reconnect_timeout())
if self._num_connections == 0 and not self.shared:
self.delete()
if not self.shared:
self._delete_task = background_tasks.create(delete_content())

def handle_event(self, msg: Dict) -> None:
"""Forward an event to the corresponding element."""
Expand Down
4 changes: 2 additions & 2 deletions nicegui/nicegui.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,13 @@ async def _on_handshake(sid: str, data: Dict[str, Any]) -> bool:


@sio.on('disconnect')
async def _on_disconnect(sid: str) -> None:
def _on_disconnect(sid: str) -> None:
query_bytes: bytearray = sio.get_environ(sid)['asgi.scope']['query_string']
query = urllib.parse.parse_qs(query_bytes.decode())
client_id = query['client_id'][0]
client = Client.instances.get(client_id)
if client:
await client.handle_disconnect()
client.handle_disconnect()


@sio.on('event')
Expand Down

0 comments on commit b4916b9

Please sign in to comment.