Close a task in Python based on condition

我与影子孤独终老i 提交于 2021-02-05 11:24:37

问题


I'm using AsyncIO and the Websockets module to create two concurrent tasks in Python, each one connects to a websocket server and receives messages.

I'm trying to create a system where, when a task did not receive messages for more than 4 seconds, it must close the connection and the task, but i'm having an hard time figuring that out. Can anyone help me out on this?

Here is what i tried:

async def connect(URI):
    async with websockets.client.connect(URI) as ws:
        LastUpdate = time.time()
        while time.time() - LastUpdate < 4:
            LastUpdate = time.time()
            await ws.recv()

        print('Not receiving updates anymore')
                
async def main():
    Tasks = [asyncio.create_task(connect('URI1')), asyncio.create_task(connect('URI2'))]

    await asyncio.gather(*Tasks)

Here, main creates two concurrent tasks and runs both of them. connect takes care of connecting and receiving messages. What i tried to do is to break the while loop when the last update was more than 4 seconds ago, but that didn't work since the loop doesn't get broken.


回答1:


You can use asyncio.wait_for:

async def connect(URI):
    async with websockets.client.connect(URI) as ws:
        while True:
            try:
                msg = await asyncio.wait_for(ws.recv(), 4)
            except asyncio.TimeoutError:
                break
            # do something with msg

        print('Not receiving updates anymore')



回答2:


There are a couple ways to do this.

  1. You can set a timeout in the package you are using within the async routine.
  2. You can use asyncio and terminate tasks when they reach a timeout.
  3. You can use non-blocking sockets for all operations, and not use asyncio at all, but use select() or poll(). This is very efficient but a lot more complex.

I would go in this order, the first one being the easiest and most preferred in most cases. Websockets seem to handle timeouts: https://github.com/websocket-client/websocket-client/blob/29c15714ac9f5272e1adefc9c99b83420b409f63/websocket/_socket.py#L99

You probably want to set a timeout on the socket. Generally this is done with https://docs.python.org/3.8/library/socket.html#socket.socket.settimeout

I suppose websockets expose this functionality somewhere though, but I am not familiar with it.



来源:https://stackoverflow.com/questions/64044426/close-a-task-in-python-based-on-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!