Chainlit / chainlit

Build Conversational AI in minutes ⚡️
https://docs.chainlit.io
Apache License 2.0
7.01k stars 924 forks source link

Chainlit doesnot send on screen if the backend task takes more than ~45 seconds #803

Open suman12345678 opened 7 months ago

suman12345678 commented 7 months ago

Describe the bug When I run any backend work more than ~ 45 seconed await cl.Message( content=response ).send() => this doesnot send any thing to screen

To Reproduce Steps to reproduce the behavior: do a time.sleep(50) response='fake response' under on_message and send some fake response and you wont see any message on screen

Expected behavior A clear and concise description of what you expected to happen. it should send 'fake response' on screen

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context Add any other context about the problem here.

suman12345678 commented 7 months ago

I have ovserved async function connect(sid, environ, auth) executed after ~ 45 seconds as a reconnection. So I gues there are 2 issues here, 1) why the reconnection is happening [reconnection is sometimes even faster issue #804 specially if I use react as frontend and chainlit as backend works is seperate docker on cloud] 2) even if reconnection happens maybe something is not handled correctly and thats why chainlit screen is not showing anything.

suman12345678 commented 7 months ago
socketissue
suman12345678 commented 7 months ago

Hi Again,

I found an option to change the setting. If you can change server.py program as a new feature , to take a parameter ping_timeout this will solve the issue to increase time limit => socket = SocketManager( app, cors_allowed_origins=[], async_mode="asgi",ping_timeout=ping_timeout_from_config )

trifonnt commented 7 months ago

Hi Again,

I found an option to change the setting. If you can change server.py program as a new feature , to take a parameter ping_timeout this will solve the issue to increase time limit => socket = SocketManager( app, cors_allowed_origins=[], async_mode="asgi",ping_timeout=ping_timeout_from_config )

I have the same issue and I have made the change you described, but there was no change. SocketManager( app, cors_allowed_origins=[], async_mode="asgi",ping_timeout=60000 )

Kind regards, Trifon

suman12345678 commented 7 months ago

Hi Again, I found an option to change the setting. If you can change server.py program as a new feature , to take a parameter ping_timeout this will solve the issue to increase time limit => socket = SocketManager( app, cors_allowed_origins=[], async_mode="asgi",ping_timeout=ping_timeout_from_config )

I have the same issue and I have made the change you described, but there was no change. SocketManager( app, cors_allowed_origins=[], async_mode="asgi",ping_timeout=60000 )

Kind regards, Trifon

Hi Trifon, what problem are you getting? are you still having problem that chainlit UI is not displaying anything if backend task takes more time? I see you put 60000, do you mean 60000 seconds? that could be too large. I used 60 second.

trifonnt commented 7 months ago

@suman12345678 I think that I have very similar to your problem. I have Chainlit with custom frontend and WebSocket connection is getting constantly closed and reopened. The same behavior is when deployed on localhost and in Kubernetes cluster.

I have increased timeout but there is no change...

Screenshot from 2024-03-12 21-51-34-1

oscar-lindholm commented 7 months ago

have you tried to wrap the code running with async? also an aporach is to add the running code into a cl_step. By doing so you will show a "running" symbol in the interface making it transparent to the user its a backend process running.

trifonnt commented 7 months ago

have you tried to wrap the code running with async? also an aporach is to add the running code into a cl_step. By doing so you will show a "running" symbol in the interface making it transparent to the user its a backend process running.

This happen immediately after opening the UI(Chainlit Custom frontend - https://github.com/Chainlit/cookbook/tree/main/custom-frontend)

ramallshore commented 7 months ago

Any update on this issue?

hyongju commented 6 months ago

@suman12345678 can you explain a bit more on how I can do the following?

Hi Again,

I found an option to change the setting. If you can change server.py program as a new feature , to take a parameter ping_timeout this will solve the issue to increase time limit => socket = SocketManager( app, cors_allowed_origins=[], async_mode="asgi",ping_timeout=ping_timeout_from_config )

SocketManager is part of the chainlit library, so should I clone the library and install the modified one? Thanks in advance.

Definite007 commented 4 months ago

Hi, I recently started a hobby project with this library and found similar issue. After debugging a bit deeper in the code, If we emulate the above given behaviour, My findings are:

When a user initiates a request to backend, an event of cl.on_message is called, but while processing the sleep command, the ping_timeout which is of 25000 ms runs out and another event of socket disconnection initiates. When this disconnect event is happening, there is no mechanism to save state of the delayed event, so that it can be completed later by re initiating the connection. Chainlit treats the socket disconnection as end of conversation, whereas there is a socket event called "clear_session" whose occurrence should be used as a flag of session end.

I dived deeper and changed the timeout to 60000ms the socket was kept live by server-client as "ping-pong" message sharing. and it was able to keep the session live for the whole delay. But in real scenarios some of the free servers don't allow prolong connection, due to which we need to save the message and response for the particular session and thread and check for socket connection, if unavailable, then create one from backend and send the generated response to frontend from the saved event context data.

KuriaMaingi commented 2 months ago

I have an IO process that is taking roughly 55 seconds and the websocket always disconnects with some version of the below. Any updates on the issue?

Exception in callback _ProactorBasePipeTransport._call_connection_lost(None) handle: <Handle _ProactorBasePipeTransport._call_connection_lost(None)> Traceback (most recent call last): File "\path\Lib\asyncio\events.py", line 84, in _run self._context.run(self._callback, *self._args) File "\path\Lib\asyncio\proactor_events.py", line 165, in _call_connection_lost self._sock.shutdown(socket.SHUT_RDWR) ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

agberoz commented 3 days ago

I was able to tackle this problem using this section

https://docs.chainlit.io/guides/sync-async#long-running-synchronous-tasks