0

我对 Twisted 和 crossbar.io 比较陌生,我目前正在使用 sqlalchemy 和 alchimia(一个使用 sqlalchemy 和 twisted 的层)进行一些数据库抽象。到目前为止,我构建的数据库抽象按预期工作,但是在我的交叉开关过程中进行异步数据库调用时遇到问题。我想那是因为我嵌套了异步调用,外部调用是一些交叉远程过程,内部是数据库访问。

我想做的是以下内容:

@inlineCallbacks
def onJoin(self, details):
  ...
  def login(user, password): # <-- outer call
    ...
    db_result = yield db.some_query(user, password) # <-- inner call
    for row in db_result: # <-- need to wait for db_result
      return 'authentication_ticket'
    return 'error'

为了能够对用户进行身份验证,我必须等待来自数据库的数据,然后发出有效票证或返回错误。目前我收到一个错误,我无法迭代延迟,因为我不等待数据库查询完成。

现在,我如何在我的登录 RPC 中等待内部 db 调用,然后对用户进行身份验证,然后返回。我知道可以在扭曲中链接异步调用,但我不知道如何在这种特殊情况下使用交叉开关以及当我的外部函数使用@inlineCallbacks快捷方式时执行此操作。

更新:

修补一下,我现在可以向 db 查询添加回调。不幸的是,现在我不知道如何将返回值从内部函数传递给外部函数(外部函数需要返回用户通过身份验证的票证):

@inlineCallbacks
  def onJoin(self, details):
  ...
  def login(user, password): # <-- outer call
    db_result = db.some_query(user, password) # <-- inner call

    def my_callback(query_result):
      if not query_result.is_empty():
        return 'user_ticket' # <-- needs to be returned by outer method

    db_result.addCallback(my_callback)

    return my_callback_result # <-- need something like that

我在我的回调函数中尝试过defer.returnValue('user_ticket'),但这给了我一个错误。

4

1 回答 1

2

您的问题似乎是,虽然login期望产生Deferreds,但它没有用@inlineCallbacks.

于 2016-01-26T20:25:22.500 回答