Я относительно новичок в 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 для входа в систему внутреннего вызова базы данных, затем аутентифицировать пользователя и затем вернуться. Я знаю, что можно связать асинхронные вызовы в Twisted, но я не знаю, как это сделать в этом особом случае с перекладиной и когда моя внешняя функция использует ярлык @inlineCallbacks
.
Обновление:
Поковырявшись, теперь я могу добавить обратный вызов к запросу БД. К сожалению, теперь я не знаю, как передать возвращаемое значение из внутренней функции во внешнюю функцию (внешняя функция должна вернуть билет, с которым пользователь проходит аутентификацию):
@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')
внутри моей функции обратного вызова, но это выдает ошибку.