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

Timeout context manager should be used inside a task #189

Open
TheNha opened this issue Apr 5, 2024 · 2 comments
Open

Timeout context manager should be used inside a task #189

TheNha opened this issue Apr 5, 2024 · 2 comments

Comments

@TheNha
Copy link

TheNha commented Apr 5, 2024

Hello,

I used Livekit Egress API, when I called start_track_composite_egress function. I got the following error :

[ERROR]   File "/usr/local/lib/python3.9/site-packages/livekit/api/egress_service.py", line 51, in start_track_composite_egress
[ERROR]     return await self._client.request(
[ERROR]
[ERROR]   File "/usr/local/lib/python3.9/site-packages/livekit/api/twirp_client.py", line 93, in request
[ERROR]     async with self._session.post(
[ERROR]
[ERROR]   File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 1194, in __aenter__
[ERROR]     self._resp = await self._coro
[ERROR]
[ERROR]   File "/usr/local/lib/python3.9/site-packages/aiohttp/client.py", line 504, in _request
[ERROR]     with timer:
[ERROR]
[ERROR]   File "/usr/local/lib/python3.9/site-packages/aiohttp/helpers.py", line 715, in __enter__
[ERROR]     raise RuntimeError(
[ERROR]
[ERROR] RuntimeError: Timeout context manager should be used inside a task

I used async_to_sync function of asgiref library from django.

async def start_track_composite_egress(start):
    return await self.lvk_api.egress.start_track_composite_egress(start)
from asgiref.sync import async_to_sync
res_track_composite = async_to_sync(start_track_composite_egress)(start)

Please help me. Thank you.

@xiaokang00010
Copy link

xiaokang00010 commented Jun 9, 2024

the same error occured to me.

here's my code:

@app.route("/api/v1/rtvc/establish", methods=["POST"])
async def establishRealTimeVoiceChat():
    if not authenticateSession():
        return {'data': 'not authenticated', 'status': False}
    if not dProvider.checkIfInitialized():
        return {'data': 'not initialized', 'status': False}

    charName = ''
    try:
        data = flask.request.get_json()
        charName = data['charName']
    except:
        return {'data': 'invalid form', 'status': False}
    
    sessionName = uuid.uuid4().hex
    session = webFrontend.chatbotManager.VoiceChatSession(sessionName, charName, dProvider)
    userName = dProvider.getUserName()
    
    userToken = livekit.api.AccessToken(
            webFrontend.config.LIVEKIT_API_KEY, webFrontend.config.LIVEKIT_API_SECRET).with_identity(
                'user').with_name(userName).with_grants(livekit.api.VideoGrants(room_join=True, room=sessionName)).to_jwt()
            
    botToken = livekit.api.AccessToken(
            webFrontend.config.LIVEKIT_API_KEY, webFrontend.config.LIVEKIT_API_SECRET).with_identity(
                'model').with_name(charName).with_grants(livekit.api.VideoGrants(room_join=True, room=sessionName)).to_jwt()
    
    # livekit api is in this file, so we can't put this logic into createRtSession
    await livekitApi.room.create_room(create=livekit.api.CreateRoomRequest(name=sessionName, empty_timeout=10*60, max_participants=2))

Update:

I came up with a solution. Define a event loop by asyncio.new_event_loop() and use it like

    # livekit api is in this file, so we can't put this logic into createRtSession
    async def f():
        await livekitApi.room.create_room(create=livekit.api.CreateRoomRequest(name=sessionName, empty_timeout=10*60, max_participants=2))
        session.start(botToken)
    
    asyncio.run_coroutine_threadsafe(f(), asyncEventLoop)

It took me at least 1 hour to solve it.

Update:

Fk it. I didn't solve it. However, it just stuck there and refused to create room. I gonna to sleep now.

Update:

My final solution is to use

async def getLiveKitAPI():
    return livekit.api.LiveKitAPI(webFrontend.config.LIVEKIT_API_URL, webFrontend.config.LIVEKIT_API_KEY, webFrontend.config.LIVEKIT_API_SECRET)

Which livekitApi should be initialized in an async def function and can't be initialized globally.

This explained.

@theomonnom
Copy link
Member

maybe you can use an asyncio event_loop and using run_until_complete?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants