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

unexpected async result #1538

Open
gongwork opened this issue Nov 21, 2024 · 1 comment
Open

unexpected async result #1538

gongwork opened this issue Nov 21, 2024 · 1 comment
Labels
bug Something isn't working needs-triage

Comments

@gongwork
Copy link

Describe the bug
I am new to chainlit, prepare the following test, expect async to be unblocking, but the timestamps show otherwise

To Reproduce
Here is the code

import chainlit as cl
from chainlit import make_async, run_sync
import time 
from datetime import datetime

def ts():
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def wait_for(t:float):
    ts_1 = ts()
    time.sleep(t)
    ts_2 = ts()
    return f"\tSYNC slept {t} sec \t[{ts_1}] ==> [{ts_2}]"

async def await_for(t:float):
    ts_1 = ts()
    time.sleep(t)
    ts_2 = ts()
    return f"\tASYNC slept {t} sec \t[{ts_1}] ==> [{ts_2}]"


@cl.on_message
async def main(message: cl.Message):
    # Your custom logic goes here

    msg = f"\n[{ts()}] Starting '{message.content}' ..."

    sleeper_0 = wait_for(5)
    msg += f"\n[{ts()}] sleeper_0 (S): {sleeper_0}"

    sleeper_1 = await await_for(2) 
    msg += f"\n[{ts()}] sleeper_1 (A): {sleeper_1}"

    sleeper_2 = await await_for(4) 
    msg += f"\n[{ts()}] sleeper_2 (A): {sleeper_2}"

    # convert to sync
    sleeper_3 = run_sync(await_for(3))
    msg += f"\n[{ts()}] sleeper_3 (S): {sleeper_3}"

    # convert to async
    af = make_async(wait_for)
    sleeper_4 = await af(7)
    msg += f"\n[{ts()}] sleeper_4 (A): {sleeper_4}"

    msg += f"\n[{ts()}] Done processing !!!"

    # Send a response back to the user
    await cl.Message(
        content=msg,
    ).send()

Results:

[2024-11-20 20:20:22] Starting 'chainlit' ...
[2024-11-20 20:20:27] sleeper_0 (S): 	SYNC slept 5 sec 	[2024-11-20 20:20:22] ==> [2024-11-20 20:20:27]
[2024-11-20 20:20:29] sleeper_1 (A): 	ASYNC slept 2 sec 	[2024-11-20 20:20:27] ==> [2024-11-20 20:20:29]
[2024-11-20 20:20:33] sleeper_2 (A): 	ASYNC slept 4 sec 	[2024-11-20 20:20:29] ==> [2024-11-20 20:20:33]
[2024-11-20 20:20:36] sleeper_3 (S): 	ASYNC slept 3 sec 	[2024-11-20 20:20:33] ==> [2024-11-20 20:20:36]
[2024-11-20 20:20:43] sleeper_4 (A): 	SYNC slept 7 sec 	[2024-11-20 20:20:36] ==> [2024-11-20 20:20:43]
[2024-11-20 20:20:43] Done processing !!!

Expected behavior
starting timestamp for sleeper_2 should be the same as that for sleeper_1

Desktop (please complete the following information):

  • OS: [Ubuntu]
  • Browser [chrome]
  • Version [1.3.2]
@dosubot dosubot bot added the bug Something isn't working label Nov 21, 2024
@hadarsharon
Copy link

@gongwork Hi, regardless of how Chainlit should behave, I think there are 2 parts of your code that are blocking as expected in Python:

  1. You are awaiting the async function in main - if you really wanted them to sleep at the same time, you could use asyncio.gather() instead.
  2. In your async function, you are using time.sleep() whereas I would recommend using asyncio.sleep() and awaiting it

With some minor modifications to your code, I get the expected behaviour (pardon me for omitting the chainlit context, I didn't see it relevant):

import time
from datetime import datetime
import asyncio

def ts():
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def wait_for(t:float):
    ts_1 = ts()
    time.sleep(t)
    ts_2 = ts()
    return f"\tSYNC slept {t} sec \t[{ts_1}] ==> [{ts_2}]"

async def await_for(t:float):
    ts_1 = ts()
    await asyncio.sleep(t)
    ts_2 = ts()
    return f"\tASYNC slept {t} sec \t[{ts_1}] ==> [{ts_2}]"

async def main():
    msg = f"\n[{ts()}] Starting 'chainlit' ..."
    sleeper_0 = wait_for(5)
    msg += f"\n[{ts()}] sleeper_0 (S): {sleeper_0}"
    sleeper_1, sleeper_2 = await asyncio.gather(await_for(2), await_for(4))
    msg += f"\n[{ts()}] sleeper_1 (A): {sleeper_1}"
    msg += f"\n[{ts()}] sleeper_2 (A): {sleeper_2}"
    print(msg)

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs-triage
Projects
None yet
Development

No branches or pull requests

2 participants