0

I'm relatively new to Twisted and crossbar.io and I'm currently working on some database abstractions using sqlalchemy and alchimia (a layer to use sqlalchemy with twisted). The db abstractions I build so far are working as expected but I get problems when making asynchronous db calls inside my crossbar procedures. I guess that is because i have nested asynchronous calls with the outer call being some crossbar remote procedure and the inner being the database access.

What i want to do is the following:

@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'

To be able to authenticate the user i have to wait for the data from the db and then either issue a valid ticket or return an error. Currently I get an error that i cannot iterate over an deferred, because i don't wait for the db query to be finished.

Now, how do i wait inside my login RPC for the inner db call, then authenticate the user and then return. I know it is possible to chain asynchronous calls in twisted, but i don't know how to do this in this special case with crossbar and when my outer function uses the @inlineCallbacks shortcut.

Update:

Tinkering around I now can add a callback to the db query. Unfortunately now I don't know how to pass a return value from the inner function to the outer function (the outer function needs to return the ticket the user gets authenticated with):

@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

I tried defer.returnValue('user_ticket') inside my callback function but this gives me an error.

7tupel
  • 73
  • 6

1 Answers1

2

Your problem appears to be that while login is expecting to yield Deferreds, it isn't decorated with @inlineCallbacks.

Glyph
  • 31,152
  • 11
  • 87
  • 129