Henry Henry - 2 months ago 19
Python Question

how to get value from returned instance of deferred

I use txmongo lib as the driver for mongoDB.
In its limited docs, the find function in txmongo will return an instance of deferred, but how can I get the actual result (like {"IP":11.12.59.119})?? I tried yield, str() and repr() but does not work.

def checkResource(self, resource):
""" use the message to inquire database
then set the result to a ip variable
"""
d = self.units.find({'$and': [{'baseIP':resource},{'status':'free'}]},limit=1,fields={'_id':False,'baseIP':True})
#Here above, how can I retrieve the result in this deferred instance??
d.addCallback(self.handleReturnedValue)
d.addErrback(log.err)
return d

def handleReturnedValue(self, returned):
for ip in returned:
if ip is not None:
d = self.updateData(ip,'busy')
return d
else:
return "NA"

Answer

If you want to write asynchronous code in twisted looking more like synchronous, try using defer.inlineCallbacks

This is from the docs: http://twisted.readthedocs.io/en/twisted-16.2.0/core/howto/defer-intro.html#inline-callbacks-using-yield

Consider the following function written in the traditional Deferred style:

def getUsers():
   d = makeRequest("GET", "/users")
   d.addCallback(json.loads)
   return d

using inlineCallbacks, we can write this as:

from twisted.internet.defer import inlineCallbacks, returnValue

@inlineCallbacks
def getUsers(self):
    responseBody = yield makeRequest("GET", "/users")
    returnValue(json.loads(responseBody))

EDIT:

def checkResource(self, resource):
    """ use the message to inquire database
        then set the result to a ip variable
    """
    returned = yield self.units.find({'$and': [{'baseIP':resource},{'status':'free'}]},limit=1,fields={'_id':False,'baseIP':True})
    # replacing callback function
    for ip in returned:
        if ip is not None:
            d = self.updateData(ip,'busy') # if this returns deferred use yield again
            returnValue(d)            
    returnValue("NA")
Comments