c4urself
c4urself

Reputation: 4287

Refactoring a Tornado Request Handler

So I have repeating code that I do for many GETs -- checking whether the response was cached previously and returning that if it is available.

The code I'd like to get working looks like this:

class Handler(web.RequestHandler):

    @gen.coroutine
    def get_cache(self):
        try:
            response = yield gen.Task(get_redis)
        except:
            logging.log()
        if response:
            self.finish(response)
            raise gen.Return()


    @gen.coroutine
    @asynchronous
    def get(self):
        self.get_cache()

        response = do_sql_get()

        self.set_cache(key, response)
        self.finish(response)

What's happening now is that it gets the cache if there but continues running the rest of the code in self.get. That it does this makes sense to me, but I'm not sure how to refactor it properly with it stopping as soon as self.finish is called in the self.get_cache method.

Upvotes: 0

Views: 392

Answers (1)

Ben Darnell
Ben Darnell

Reputation: 22154

get_cache should return a value that indicates whether it finished the request or not (or it should return the cached data and leave it to the caller to finish the request). I would do one of the following:

@gen.coroutine
def serve_from_cache(self):
  response = yield gen.Task(get_redis)
  if response:
      self.finish(response)
      raise gen.Return(True)
  else:
      raise gen.Return(False)

@gen.coroutine
def get(self):
  if (yield self.serve_from_cache()):
    return
  # do work
  yield self.set_cache(...)

or

@gen.coroutine
def get_cache(self):
    return yield gen.Task(get_redis)


@gen.coroutine
def get(self):
    resp = yield self.get_cache()
    if resp:
      self.finish(resp)
      return
    # do work...

Upvotes: 2

Related Questions