-----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
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-devel