human
Complete this python program:
def cached(method):
assistant
#Here is the Python code you requested.

    """decorator for a cached page.
    This only handles getting from the cache, not writing to it.
    Writing to the cache must be handled in the decorated method.
    """
    @gen.coroutine
    def cached_method(self, *args, **kwargs):
        uri = self.request.path
        short_url = self.truncate(uri)
        if self.get_argument('flush_cache', False):
            (yield self.rate_limiter.check(self))
            app_log.info('flushing    cache    %s', short_url)
            (yield method(self, *args, **kwargs))
            return
        pending_future = self.pending.get(uri, None)
        loop = IOLoop.current()
        if pending_future:
            app_log.info('Waiting    for    concurrent    request    at    %s', short_url)
            tic = loop.time()
            (yield pending_future)
            toc = loop.time()
            app_log.info('Waited    %.3fs    for    concurrent    request    at    %s', (toc - tic), short_url)
        try:
            with time_block(('cache    get    %s' % short_url)):
                cached_pickle = (yield self.cache.get(self.cache_key))
            if (cached_pickle is not None):
                cached = pickle.loads(cached_pickle)
            else:
                cached = None
        except Exception as e:
            app_log.error('Exception    getting    %s    from    cache', short_url, exc_info=True)
            cached = None
        if (cached is not None):
            app_log.info('cache    hit    %s', short_url)
            for (key, value) in cached['headers'].items():
                self.set_header(key, value)
            self.write(cached['body'])
        else:
            app_log.debug('cache    miss    %s', short_url)
            (yield self.rate_limiter.check(self))
            future = self.pending[uri] = Future()
            try:
                (yield method(self, *args, **kwargs))
            finally:
                self.pending.pop(uri, None)
                future.set_result(None)
    return cached_method