On Fri, 2008-02-15 at 23:12 +0100, Duncan Webb wrote: > Thanks for the examples but all they show me is that you can only yield > from other coroutines and can call a callback, but what I can't figure > out is how to pass a result (except in-progress objects) back from > either a coroutine or a callback.
Only coroutines can yield, yes. If you are calling a coroutine foo(), then you have three options: 1. wait() on the InProgress returned by foo() 2. connect() a result handler to the InProgress returned by foo() 3. make sure function you are calling foo() from is also decorated with @coroutine, and then just yield the InProgress returned by foo() coroutines "return" values by yielding objects other than NotFinished or InProgress. Anything else means the coroutine is finished. > ~ @kaa.coroutine() > ~ def ping(self): > ~ inprogress = self.server.rpc('ping') > ~ yield inprogress > ~ result = inprogress.get_result() You are getting the result from the asynchronous rpc, but you're not doing anything with it. This is roughly what you want: @kaa.coroutine() def ping(self): inprogress = self.server.rpc('ping') yield inprogress yield inprogress.get_result() The first yield is an InProgress object. This means the ping() is resumed when inprogress is finished. Then ping() yields the value of inprogress.get_result(), which is the return value of remote procedure 'ping'. If the remote procedure raised an exception, get_result() will raise that exception locally. > if __name__ == '__main__': > > ~ rec = Rec() > ~ f = rec.ping().connect(handle_result) > ~ print 'f=%r' % f Signal.connect() (InProgress inherits Signal) doesn't return anything interesting. It just returns the callback you just connected. But this implements option #2 above. > ~ p = rec.ping() > ~ print 'p=%r' % p > > ~ r = p.get_result() > ~ print 'r=%r' % r This won't work. You are calling get_result() immediately on the InProgress object, without waiting for it to finish. So you again are left with the first two options I listed at the top of this email. Either use wait(), or connect a result handler (which you had already done earlier). For the purposes of your test, since you are executing it from the global scope, it's fine to call wait(). r = rec.ping().wait() > If I put the get_result code in a coroutine then it should work, but I > still have an inprogress object from this coroutine and I want the > result outside a kaa.coroutine. Options #1 or #2. #2 is better, for the reasons already discussed. > If you see what I mean. I _think_ I do. My sense from your questions is that your mindset is still very much synchronous. You have all these asynchronous tools at your disposal, but I think it does require a different frame of mind. > But I'm really *not* happy that it is not possible to sync an rpc call > at some time in the future, except with the wait() but it's use is > frowned upon. Option #2, connect() a result handler to the InProgress returned by the rpc call. The result handler then does whatever it needs to do when the rpc call has finished. This allows you to handle the result asynchronously, without calling wait(), and without needing another coroutine. > The name coroutine is much better than yield_function, it does make the > concept clear. Agreed. :) Cheers, Jason. ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Freevo-devel mailing list Freevo-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freevo-devel