1

I have the following code to send result to browser based on the api call.

import tornado.ioloop
import tornado.web
from tornado import gen
from datetime import date



class GetGameByIdHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self, id):
        response = { 'id': int(id),
                     'name': 'Crazy Game',
                     'release_date': date.today().isoformat() }
        self.set_header('Content-Type', 'text/json')
        self.write(response)


        for i in range(10000000):
            for j in range(10):
                pass
        print i


application = tornado.web.Application([
    (r"/getgamebyid/([0-9]+)", GetGameByIdHandler),
], debug = True)



if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

I want that the api should return result as soon as self.write is encountered. The for loop should be run after that. How can I get this done? Basically, I don't want to return the result immediately.

NOTE: The loop here has no real purpose except to demonstrate the sending of result is delayed just because of this extra thing in the get function.

A less abstract example:

import tornado.ioloop
import tornado.web
from tornado import gen
from datetime import date



class GetGameByIdHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self, id):
        result_dict = GetResultsFromDB(id)
        response = result_dict
        self.set_header('Content-Type', 'text/json')
        self.write(response)

        # Basically i want to doSomething basedon results
        # Generated from DB
        for key in result_dict:
            if result_dict[key] == None:
                DoSomething()


application = tornado.web.Application([
    (r"/getgamebyid/([0-9]+)", GetGameByIdHandler),
], debug = True)



if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
Shishir Pandey
  • 832
  • 1
  • 12
  • 23

1 Answers1

1

if you need to run some code after writing all data to a socket, you can use tornado.web.RequestHandler.flush:

    self.write(response)
    self.flush(callback=lambda: DoSomethingWrapper(response))
Aprillion
  • 21,510
  • 5
  • 55
  • 89
  • This works fine. But if `DoSomething` is going on then another http get request waits for previous request to get over. How can avoid it? – Shishir Pandey Jul 07 '16 at 16:00
  • 1
    hm, have a look at [How to best perform Multiprocessing within requests with the python Tornado server?](http://stackoverflow.com/questions/15375336/how-to-best-perform-multiprocessing-within-requests-with-the-python-tornado-serv) and similar topics – Aprillion Jul 07 '16 at 17:58