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

Service large amount of data results in timeout and app non response #140

Open
thondeboer opened this issue Sep 23, 2023 · 5 comments
Open
Assignees
Labels
enhancement New feature or request

Comments

@thondeboer
Copy link

I am trying to serve quite a bit of information but get timeouts as shown below and app becomes unresponsive

  • Three pages
  • One page with a repeater with up to 10 items with 2 matplotlib images, 1 vega lite image and 3 data frames, one containing about 35,0000 rows with 10 columns
  • and additional fairly simple plotly plot

I tried to make some of the data invisible, since it is not needed until user wants to see it, but that does not help.

Any ideas on how to avoid this timeout? Or can we extend the teimeout somewhere in the settings>

Task exception was never retrieved
future: <Task finished name='Task-108' coro=<get_asgi_app.<locals>._handle_state_enquiry_message() done, defined at /home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/streamsync/serve.py:265> exception=ConnectionClosedError(None, Close(code=1011, reason='keepalive ping timeout'), None)>
Traceback (most recent call last):
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 979, in transfer_data
    await asyncio.shield(self._put_message_waiter)
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/streamsync/serve.py", line 279, in _handle_state_enquiry_message
    await websocket.send_json(response.model_dump())
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/starlette/websockets.py", line 173, in send_json
    await self.send({"type": "websocket.send", "text": text})
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/starlette/websockets.py", line 85, in send
    await self._send(message)
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 65, in sender
    await send(message)
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 320, in asgi_send
    await self.send(data)  # type: ignore[arg-type]
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 635, in send
    await self.ensure_open()
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 944, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: sent 1011 (unexpected error) keepalive ping timeout; no close frame received
Task exception was never retrieved
future: <Task finished name='Task-185' coro=<get_asgi_app.<locals>._handle_state_enquiry_message() done, defined at /home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/streamsync/serve.py:265> exception=ConnectionClosedError(None, Close(code=1011, reason='keepalive ping timeout'), None)>
Traceback (most recent call last):
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 979, in transfer_data
    await asyncio.shield(self._put_message_waiter)
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/streamsync/serve.py", line 279, in _handle_state_enquiry_message
    await websocket.send_json(response.model_dump())
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/starlette/websockets.py", line 173, in send_json
    await self.send({"type": "websocket.send", "text": text})
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/starlette/websockets.py", line 85, in send
    await self._send(message)
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 65, in sender
    await send(message)
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 320, in asgi_send
    await self.send(data)  # type: ignore[arg-type]
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 635, in send
    await self.ensure_open()
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 944, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: sent 1011 (unexpected error) keepalive ping timeout; no close frame received
Task exception was never retrieved
future: <Task finished name='Task-109' coro=<get_asgi_app.<locals>._handle_state_enquiry_message() done, defined at /home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/streamsync/serve.py:265> exception=ConnectionClosedError(None, Close(code=1011, reason='keepalive ping timeout'), None)>
Traceback (most recent call last):
  File "/home/tdeboer/.cache/pypoetry/virtualenvs/rnayx-eqgCBscA-py3.10/lib/python3.10/site-packages/websockets/legacy/protocol.py", line 979, in transfer_data
    await asyncio.shield(self._put_message_waiter)
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:
.
.
.
@thondeboer
Copy link
Author

thondeboer commented Sep 23, 2023

I guess what we really need is server-based paging of large dataframes like we can do in Dash. Could implement ourserlves I guessif we can catch some of the events, like sort on a dataframe

@FabienArcellier
Copy link
Collaborator

FabienArcellier commented Sep 23, 2023

I don't know pretty well the architecture. I think the websocket link timeout is 20 seconds on uvicorn. This setting is not editable in the current implementation.

You may try temporarily to modify the line 404 of streamsync.serve:server in your venv to see how it impact your situation and add ws_ping_timeout ?

uvicorn.run(asgi_app, host=host,
                port=port, log_level=log_level, ws_max_size=MAX_WEBSOCKET_MESSAGE_SIZE, ws_ping_timeout=600)

Could you share more details about the volume your application is trying to fetch using the browser inspector ?

image

@FabienArcellier
Copy link
Collaborator

FabienArcellier commented Sep 23, 2023

Did you try to bind visibility on a variable in the state and keep the state empty till the visibility variable is triggerd on the backend ?

def handle_timer_tick(state: StreamsyncState):
    if state['tick_visible'] is False:
        return

    df = state["random_df"]
    for i in range(5):
        df[f'pgcf_{i+1}'] = np.around(np.random.rand(10, 1), decimals=9)
    state["random_df"] = df

def trigger_auto_refresh(state: StreamsyncState):
    state["tick_visible"] = not state["tick_visible"]

@thondeboer
Copy link
Author

Yeah, I'll consider doing this to create the data until requested. Will also look at the messages as you suggested above

@FabienArcellier
Copy link
Collaborator

I have described a design to chunk frame inside the websocket payload. It will ensure we keep the frame below a size and highly reduce the risk of timeout : FabienArcellier#12

It involves adding an encoder / decoder on backend / frontend to rebuild the frame.

@FabienArcellier FabienArcellier added the enhancement New feature or request label Mar 13, 2024
@FabienArcellier FabienArcellier changed the title Servince large amount of data results in timeout and app non response Service large amount of data results in timeout and app non response Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants