Search code examples
pythonasynchronouswebsockettornado

bottleneck in python tornado websocket server


I have a websocket server written in python tornado. the server will receive many connections from clients and as you know, we have on_message function that is fired when a websocket message is received. so, here is my question that if a message(say request from client) need 5 sec to be processed then when the server is processing some request, the server goes in blocking mode and can't accept or receive more connection or data. after some research i figure out that Asyncio can resolve my problem but i don't now know to use it. so, how do i call process method to avoid blocking?

following is my code:

class WavesClient(tornado.websocket.WebSocketHandler):
    def check_origin(self, origin):
        return True
    def open(self):
        print("New client connected")

   def on_message(self, message):
        self.process(message)

   def on_close(self):
        print("Client disconnected")
   def process(self,message):
        #it takes 5 sec to complete

Solution

  • I use tornado primarily to host my webapps, therefore I can tell you if any part of your code in tornado is blocking, the whole server will block.

    Now to your code:

    @tornado.gen.coroutine
    def on_message(self, message):
        process_results = yield self.process(message)
        self.write_message(process_results)
    
    @tornado.gen.coroutine
    def process(self, message):
        # a long process, this is the equivalent of time.sleep(2) which is blocking
        yield tornado.gen.sleep(2)
        return 'finished'
    

    With tornado you have to yield from a function to get the return value. Also, if your function is yielding, you must wrap it using the tornado.gen.coroutine decorator

    This question is similar to yours. And the answer is informative as well.