2015-04-20 4 views
3

Я хочу украсить метод GET coroutine, который определяет, нужно ли читать данные из кеша и устанавливать кеширование данных. Но я не знаю, как обернуть сопрограмму. Вот как я это делаю сейчас:В Tornado, как «украсить» функцию GET coroutine

def cache_it(f): 
    @functools.wraps(f) 
    @coroutine 
    def wrapper(self, *args, **kwargs): 
     key = self.get_cache_key() 
     result = cache.get(key) 
     if not result: 
      yield f(self, *args, **kwargs) 
      if self._result_buffer: 
       cache.set(key, self._result_buffer) 
     else: 
      self._result_buffer = result 

class BaseHandler(RequestHandler): 
    def __init__(self, *args, **kwargs): 
     super(BaseHandler, self).__init__(*args, **kwargs) 
     self._result_buffer = [] 

    def write(self, chunk): 
     self._result_buffer.append(chunk) 

    def flush(self, include_footers=False, callback=None): 
     self._flush_result_buffer() 
     super(BaseHandler, self).flush(include_footers) 

    def finish(self, chunk=None): 
     if chunk is not None: 
      self.write(chunk) 
     self._flush_result_buffer() 
     super(BaseHandler, self).finish() 

    def _flush_result_buffer(self): 
     for r in self._result_buffer: 
      super(BaseHandler, self).write(r) 
     self._result_buffer = [] 

class IndexHandler(RequestHandler): 

    @cache_it 
    @coroutine 
    def get(self): 
     ... 
     self.write({'data': data}) 

Но это не работает. Пожалуйста, дайте мне знать, как это сделать и где я ошибаюсь.

ответ

2

Af первый. сопрограммная должна быть фиксированной (Просто добавьте возврат):

def cache_it(f): 
    @functools.wraps(f) 
    @coroutine 
    def wrapper(self, *args, **kwargs): 
     key = self.get_cache_key() 
     result = cache.get(key) 
     if not result: 
      yield f(self, *args, **kwargs) 
      if self._result_buffer: 
       cache.set(key, self._result_buffer) 
     else: 
      self._result_buffer = result 
    return wrapper 

И здесь также должно быть исправлено:

class IndexHandler(BaseHandler): 

Теперь вы можете кэшировать результирующий буфер (примечание: это список).

+0

Привет @sinceq, он работает сейчас, но теперь у меня есть другая проблема с операцией async memcache. Я пробовал https://github.com/dpnova/tornado-memcache, но я не знаю, как его использовать в сопрограмме coroutine (оболочка в функции cache_it) –

Смежные вопросы