私は比較的 Twisted と crossbar.io に慣れていません。現在、sqlalchemy と alchimia (twisted で sqlalchemy を使用するためのレイヤー) を使用してデータベースの抽象化に取り組んでいます。これまでに作成した db 抽象化は期待どおりに機能していますが、クロスバー プロシージャ内で非同期 db 呼び出しを行うと問題が発生します。これは、外側の呼び出しがクロスバー リモート プロシージャであり、内側がデータベース アクセスである非同期呼び出しをネストしたためだと思います。
私がやりたいことは次のとおりです。
@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'
ユーザーを認証できるようにするには、データベースからのデータを待ってから、有効なチケットを発行するか、エラーを返す必要があります。現在、db クエリが完了するのを待たないため、遅延を反復処理できないというエラーが発生します。
ここで、ログイン RPC 内で内部データベース呼び出しを待機し、ユーザーを認証してから戻るにはどうすればよいですか。ツイストで非同期呼び出しをチェーンできることは知っていますが、クロスバーを使用したこの特別なケースと、外部関数が@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')
コールバック関数内で試しましたが、エラーが発生します。