トルネードについて頭を悩ませようとしています。私はmongodbに裏打ちされたチャットアプリケーションを作成しており、motor
それへの非ブロックアクセスに使用しています。
私が達成しようとしているのは次のとおりです。
motor
mongo からユーザーのレコードを非同期にプルするために使用するデコレーターを作成します。- 資格情報を検証する (ユーザー名とトークン)
- 上記1.で取得したuser_idがチャットルームへのアクセスを許可されていることを確認する別のデコレーターを作成します。
motor
これには、「ChatRoom」レコードを取得するために、mongo への別の非同期呼び出しが必要です。 - 問題がなければチャットルームに登録する
デコレータ 1. が動作しています (基本的にhttp://tornadogists.org/5251927/から取得):
def authenticated_async(f):
@functools.wraps(f)
@gen.engine
def wrapper(self, *args, **kwargs):
self.current_user = yield gen.Task(self.get_current_user_async)
if self.current_user:
logging.info("User '%s' (%s) successfully authenticated" %
(self.current_user['username'],
self.current_user['_id']))
f(self, *args, **kwargs)
else:
raise tornado.web.HTTPError(401, "User not authenticated, "
"aborting")
return wrapper
問題は、2 番目のデコレータの場合、 にアクセスする必要があることですself.current_user
。これは非同期コールバックで設定されるため、デコレーターに入ったときには使用できませんvalidation
(つまり、認証デコレーターが完了する前に検証デコレーターが呼び出されます)。
非同期関数でこのようにデコレータを使用することはできませんか? True であることを確認した後、上記のメソッド内で検証メソッドを呼び出すだけでよいself.current_user
ので、コールバックのようになりますか?
Handler のメソッドをこれらのデコレータの両方でラップして、別の場所で再利用できるようにしたいのが理想です。
class ChatSocketHandler(tornado.websocket.WebSocketHandler):
@gen.coroutine
@validate_invitation_access_async
@authenticated_async
def open(self, invitation_id):
# do stuff here...
更新
実際、依存関係はありません。user_id はパラメーターとして提供され、両方のデコレーターを並行して実行するために使用できます。1 つは認証を確認するため、もう 1 つはその ID を持つユーザーがルームへのアクセスを許可されているかどうかを確認するためです。open()
メソッドは、の場合にのみ続行されますself.auth_check == True and self.room_check == True
。
open()
ただし、非同期デコレータが完了する前に呼び出されることはありますか?