Hi Nick;

Thanks for the answer. However, If I take the while loop out,  
"helloWorldTest()" returns immediately, and the Flex app gets the initial value 
of self.result. The defer.callback function doLog never gets called.  If I call 
 the "terminate()" from the Flex app, which in turn calls reactor.sop()  the 
doLog  function finally then gets called.   I am looking for what I need to do 
to allow getProcessOutput to run such that the defer.callback function doLog 
actually gets called.

I have figured out that if instead of calling getProcessOutput() directly 
within the helloWorldTest() method, that I can queue it for running  after 
helloWorldTest() as returned, as in:
    reactor.callLater(1, self. helloWorldTest2)
 and that the defer.callback function doLog does then get called.

This means that the defer.callback function doLog will get  called after the 
helloWorldTest()  has returned. I see can call helloWorldTest() , and then keep 
querying the python service from the Flex app until the  defer.callback 
function doLog  has run.

I still don't understand why calling getProcessOutput() directly within the 
helloWorldTest() method doesn't work. Any explanation would be welcome.

    Thanks,  Read Roberts

On 10/17/09 1:53 AM, "Nick Joyce" <[email protected]> wrote:

On 17 Oct 2009, at 05:15, Read Roberts wrote:

> I have a Python server using twisted which responds to pyAMF calls
> from
> Flex/Air applications (following Bruce Eckels 5/1/2008 article
> "Concurrency
> with Python, Twisted, and Flex"). The service is basically as
> follows below.
> When the client calls a service API, the API needs to make a OS
> shell call.
> I see that if I call reactor.stop() after the  getProcessOutput call
> (such
> as within the doLog and doError functions), the call happens and I
> see the
> output. How can can I retrieve the output without calling
> reactor.stop()? In
> the example below, the AIR app calls the callback helloWorldTest(),
> and the
> deferred.addCallback function is never called.
>
> import os
> from twisted.spread import pb
> from  twisted.internet.utils import getProcessOutput
> from twisted.internet import reactor
>
> class FlexInterface(pb.Root):
>    def __init__(self):
>        self.result e
>
>    def doLog(self, result):
>        self.result = "%s" % (result)
>        return result
>
>    def doError(self, failure):
>        self.result = "%s" % ( failure)
>        return failure
>
>    def helloWorldTest(self):
>        deferred = getProcessOutput("echo", ["Hello World"],
> os.environ)
>        deferred.addErrback(self.doError)
>        deferred.addCallback(self.doLog)
>        while (self.result == None)
>            print "doLog still hasn't been called"
>        return self.result


The while loop will block the event loop, preventing the deferred from
ever being called. PyAMF will accept a deferred as a return value for
the service function and will not return a response until the
deferred's callback is fired.

So, you could re-write the method like:

     def helloWorldTest(self):
         deferred = getProcessOutput("echo", ["Hello World"],
os.environ)

         deferred.addErrback(self.doError)
         deferred.addCallback(self.doLog)

         return deferred

If the deferred's callback is called then the return value of doLog
will be used as the response value. If the errback is called, the
return value of doError will be used as the response, in this case a
Failure instance. PyAMF converts Failure instances to remoting/
messaging error objects automagically, so the faultHandler on the
flash/air side will be called.

hth,

Nick


_______________________________________________
Twisted-Python mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

_______________________________________________
Twisted-Python mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to