Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get result from adbapi without becoming a Deferred

I'm working with a python twisted application that was originally written using blocking database calls. I am changing it to use adbapi so the database calls become non-blocking. I think I've pretty much got it figured out, I just want to make sure I'm not missing something.

There are parts of the code that go through a 4 or 5 function call chain, with the database result being used at the lowest level of that chain. Every function of the chain uses a regular return statement to return results to the previous level.

Do I have to change each level to a Deferred in order to do this properly or is there some way to get and use the database result while still using a regular return statement? Simplified example:

def db_query():
    cur.execute("SELECT * FROM table")
    return cur.fetchone()

def f2():
    result = db_query()
    print result 
    return result 

def f1():
    result = f2()
    result.reverse()
    print result

In order to change the db_query to a non-blocking call, it has to become (or return) a Deferred. So in order to use the results in the other functions, I need to change them to that as well, because they need to yield the value in order to use it, right?

@defer.inlineCallbacks
def db_query():
    result = yield dbpool.runQuery("SELECT * FROM table")
    defer.returnValue(result[0])

@defer.inlineCallbacks
def f2():
    result = yield db_query()
    print result
    defer.returnValue(result)

@defer.inlineCallbacks
def f1():
    result = yield f2()
    result.reverse()
    print result

So my question is: Is there a way to access, use, and return the database result in functions f2 and f1 without having to turn them into Deferreds? I think the answer is no, but I want to make sure before I really start refactoring the whole codebase for this.

like image 829
metsfan Avatar asked Jan 25 '26 00:01

metsfan


1 Answers

Yep, I understood it correctly. Any function that needs to use and return the data in the call chain has to be or return a deferred. If there's a function in the chain that doesn't use the data but just passes it along, it can do just that with a regular return statement.

like image 197
metsfan Avatar answered Jan 27 '26 14:01

metsfan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!