-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jason Tackaberry wrote: | 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.
Okay, I get it, and thanks this is a good explanation. Back to the original problem, where coroutines don't seem to work with kaa.rpc in the recordserver. There work, fail or block. An example of them blocking is in a previous mail. Here are some cut down (prints and comments removed) bits of the record_client.py: ~ @kaa.coroutine() ~ def pingCo(self): ~ inprogress = self.recordserver_rpc('ping') ~ yield inprogress ~ yield inprogress.get_result() This works and returns True ~ def findNextProgramNow(self): ~ progress = self.recordserver_rpc('findNextProgram') ~ if progress is None: ~ return None ~ progress.wait() ~ result = progress.get_result() ~ return result This works and returns the next program to record (takes about 50ms on a P3) ~ def findNextProgram(self, callback): ~ """ Find the next program using a callback function """ ~ return self.server_rpc('findNextProgram', callback) This also works and returns the next program to record ~ @kaa.coroutine() ~ def findNextProgramCo(self): ~ """ """ ~ progress = self.recordserver_rpc('findNextProgram') ~ yield progress ~ yield progress.get_result() This fails with an exception: Traceback (most recent call last): ~ File "record_client.py", line 549, in ? ~ r = rc.findNextProgramCo().wait() ~ File "/usr/lib/python2.4/site-packages/kaa/notifier/async.py", line 328, in wait ~ return self.get_result() ~ File "/usr/lib/python2.4/site-packages/kaa/notifier/async.py", line 284, in get_result ~ raise type, value, tb AttributeError: 'object' object has no attribute 'title' Cheers, Duncan -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHtsNUNi6l+Xvys44RAn/uAJ98YXxwTPpYUvg2wDkBvr1c9PbexQCdF5b4 3b/6iaUh8pb7gky6LXamKKc= =5Mh3 -----END PGP SIGNATURE----- ------------------------------------------------------------------------- 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