Search code examples
pythonasynchronoustornadoyield

Calling function from Tornado async


just struggling on this. If i have an async request handler that during it's execution calls other functions that do something (for example async db queries) and then they call "finish" on their own, do i have to mark them as async? because if the application is structured like the example, i get errors about multiple calls to "finish". I guess i miss something.

class MainHandler(tornado.web.RequestHandler):

    @tornado.web.asynchronous
    @gen.engine
    def post(self):
        #do some stuff even with mongo motor
        self.handleRequest(bla)

    @gen.engine
    def handleRequest(self,bla):
        #do things,use motor call other functions
        self.finish(result)

Do all functions have to be marked with async? thanks


Solution

  • Calling finish ends the HTTP request see docs. Other functions should not call 'finish'

    I think you want to do something like this. Note that there is a extra param 'callback' which is added into async functions:

    @tornado.web.asynchronous
    @gen.engine
    def post(self):
        query =''
        response = yield tornado.gen.Task(
            self.handleRequest,
            query=query
        )
        result = response[0][0]
        errors = response[1]['error']
        # Do stuff with result
    
    def handleRequest(self, callback, query):
         self.motor['my_collection'].find(query, callback=callback)
    

    See tornado.gen docs for more info