Calling a coroutine from asyncio.Protocol.data_received

前端 未结 1 1663
小鲜肉
小鲜肉 2020-12-05 11:42

This is similar to Calling coroutines in asyncio.Protocol.data_received but I think it warrants a new question.

I have a simple server set up like this



        
相关标签:
1条回答
  • 2020-12-05 12:43

    You need to add your coroutine to the event loop, and then use Future.add_done_callback to handle the result when the coroutine completes:

    @asyncio.coroutine
    def go(self):
        return(yield from asyncio.sleep(3, result = b'data reply'))
    
    def data_received(self, data):
        print('Data Received', flush=True)
    
        task = asyncio.async(self.go()) # or asyncio.get_event_loop().create_task()
        task.add_done_callback(self.handle_go_result)
    
    def handle_go_result(self, task):
        data = task.result()
        self.send(data)
    

    Calling a coroutine directly in data_received just simply isn't allowed, since the caller isn't going to try to yield from it, and creating/running a new event loop inside of data_received will always end up blocking the main event loop until the inner event loop finishes its work.

    You just want to schedule some work with your main event loop (asyncio.async/loop.create_task()), and schedule a callback to run when the work is done (add_done_callback).

    0 讨论(0)
提交回复
热议问题