2017-10-30 33 views
1

私は、トルネードルートハンドラのredisとtornadisライブラリを使用してキャッシュデコレータを構築しようとしています。私のルートハンドラ内カスタムデコレータのトルネード非同期アクション

def rediscache(route): 
    def decorator(func): 
     @wraps(func) 
     def wrapper(*args, **kwargs): 
      result = yield redis.call("GET", "latest_info") 
      print(result) 
      func(*args, **kwargs) 
     return wrapper 
    return decorator 

私はそうのようにそれを使用しています:

class MainHandler(tornado.web.RequestHandler): 

    def initialize(self, db, redis): 
     self.db = db 
     self.quakes = self.db.quakes 
     self.redis = redis 

    @gen.coroutine 
    @rediscache('route_is_here') 
    def get(self): 
     ''' ... handler logic here ... ''' 

問題は、私は私のデコレータを使用している場合、私はウェブへの出力を見て停止することである これは私がこれまで持っているものです私のハンドラから。

私は...

result = redis.call("GET", "latest_info") 

はその後、私は再び私のブラウザに出力を見始めるが、これはそれを行うための適切な方法ではなく、場合...?これはまだ非同期ですか?そうでない場合は、それを行う方法は何ですか?ありがとう!あなたはyieldコルーチンする場合は

+0

'redis'ライブラリが非同期ではありません。しかし、「竜巻」は非同期です。私はあなたのコードのどこにでも 'tornadis' APIを使ってあなたを見ることはありません。 – xyres

+0

申し訳ありません。 "redis"は実際に竜巻のインスタンスの名前です。クライアント – Liviu

答えて

2

あなたのデコレータでWrapperがgen.coroutine次のようになります。

@rediscache('route_is_here') 
@gen.coroutine 
def get(self): 
    ''' ... handler logic here ... ''' 

編集

説明:

def rediscache(route): 
    def decorator(func): 
     @tornado.gen.coroutine 
     @wraps(func) 
     def wrapper(*args, **kwargs): 
      result = yield redis.call("GET", "latest_info") 
      print(result) 
      if not result: 
       new = yield func(*args, **kwargs) 
       # save to 
     return wrapper 
    return decorator 

あなたはデコレータの順にを変更も必要デコレータの注文

あなたは(歩留まり)デコレータであなたの元 getを待つしたい場合
@second 
@first 
def my_func(): 
    pass 

my_func = second(first(my_func)) 

と同じであるので、あなたはコルーチンので、それはrediscache前でなければなりませんを渡す必要があります。デコレータについて

詳細情報 - https://wiki.python.org/moin/PythonDecorators

+0

これはうまくいきました!しかし、デコレータを注文するロジックを説明していただけますか? – Liviu

関連する問題