-----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

Reply via email to