【发布时间】:2015-06-14 19:35:39
【问题描述】:
当我使用 get_current_user() 时,我需要异步检查 Redis 中的一些内容(使用 tornado-redis)。
我正在做以下事情:
def authenticated_async(method):
@gen.coroutine
def wrapper(self, *args, **kwargs):
self._auto_finish = False
self.current_user = yield gen.Task(self.get_current_user_async)
if not self.current_user:
self.redirect(self.reverse_url('login'))
else:
result = method(self, *args, **kwargs) # updates
if result is not None:
yield result
return wrapper
class BaseClass():
@gen.coroutine
def get_current_user_async(self,):
auth_cookie = self.get_secure_cookie('user') # cfae7a25-2b8b-46a6-b5c4-0083a114c40e
user_id = yield gen.Task(c.hget, 'auths', auth_cookie) # 16
print(123, user_id)
return auth_cookie if auth_cookie else None
例如,我想使用 authenticated_async 装饰器:
class IndexPageHandler(BaseClass, RequestHandler):
@authenticated_async
def get(self):
self.render("index.html")
但我在控制台中只有 123。
怎么了?如何解决?
谢谢!
更新
我已经用yield result 更新了代码。
在 auth_cookie 我有cfae7a25-2b8b-46a6-b5c4-0083a114c40e。
然后我去终端:
127.0.0.1:6379> hget auths cfae7a25-2b8b-46a6-b5c4-0083a114c40e
"16"
所以,
user_id = yield gen.Task(c.hget, 'auths', auth_cookie)
print(123, user_id)
必须返回
123 16
但它返回一个 123
更新 1
有
class IndexPageHandler(BaseClass, RequestHandler):
@gen.coroutine
def get(self):
print('cookie', self.get_secure_cookie('user'))
user_async = yield self.get_current_user_async()
print('user_async', user_async)
print('current user', self.current_user)
self.render("index.html",)
在控制台我有:
cookie b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
123
user_async b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
current user None
【问题讨论】:
-
如果被包装的方法本身是一个协程,则在从
authenticated_async的包装器(result = method(*args, **kwargs); if result is not None: yield result)调用它时必须让其屈服。不过,这不适用于IndexPageHandler。如果您进入 print 语句,看起来所有异步内容都在工作,而您只是从c.hget得到一个空结果(不管是什么)。如果不是这样,您能否更清楚地了解您的期望以及您所看到的? -
@BenDarnell 我已经更新了帖子。
-
没有装饰器可以工作吗?如果您直接在
handler.get中调用get_secure_cookie和c.hget(或get_current_user_async)会怎样? -
@BenDarnell 我更新了帖子
-
您需要将get() 包裹在
@gen.coroutine中,并在调用get_current_user_async()时使用yield。