Search code examples
pythontornadorethinkdbcoroutine

how to return value from tornado.ioloop.IOLoop instance add_future method


I'm using RethinkDB with Tornado with an async approach. Base on my data model in RethinkDB, upon inserting a record for my topic table, I also have to update/insert new record into user_to_topic table. Here's the basic set up of my post request handler.

class TopicHandler(tornado.web.RequestHandler):
  def get(self):
     pass

  @gen.coroutine
  def post(self, *args, **kwargs):
      # to establish databse connection
      connection = rth.connect(host='localhost', port=00000, db=DATABASE_NAME)
      # Thread the connection
      threaded_conn = yield connection

      title = self.get_body_argument('topic_title')
      # insert into table
      new_topic_record = rth.table('Topic').insert({
         'title': topic_title,
     }, conflict="error",
         durability="hard").run(threaded_conn)

     # {TODO} for now assume the result is always written successfully
     io_loop = ioloop.IOLoop.instance()
     # I want to return my generated_keys here 
     io_loop.add_future(new_topic_record, self.return_written_record_id)
     # do stuff with the generated_keys here, how do I get those keys

  def return_written_record_id(self, f):
     _result = f.result()
     return _result['generated_keys']

after the insert operation finishes, the Future object with return result from RethinkDB insert operation through Future.result() method which I can retrieve id of new record using generated_keys attribute of result. According to Tornado document, I can do stuff with the result in my callback function, return_written_record_id. Of course I can do all the other database operations inside my return_written_record_id function, but is it possible to return all the ids to my post function? Or this is the way it has to be using coroutine in tornado?

Any suggestion will be appreciated. Thank you!


Solution

  • Simply do:

    result = yield new_topic_record
    

    Whenever you yield a Future inside a coroutine, Tornado pauses the coroutine until the Future is resolved to a value or exception. Then Tornado resumes the coroutine by passing the value in or raising an exception at the "yield" expression.

    For more info, see Refactoring Tornado Coroutines.