Jason Tackaberry wrote: > On Thu, 2009-04-02 at 18:09 +0200, Duncan Webb wrote: >> This is an example of making two rpc calls in a coroutine; the result of >> the coroutine is the result of the last rpc call. Error handling was not >> implemented in this example. > > Ok, so RPC calls return InProgress objects that finish when the rpc > completes. So you yield both calls, and then finally yield the result > of the last call: > > @kaa.coroutine() > def func(remote): > yield remote.rpc('foo') > result = yield remote.rpc('bar') > yield result > > In the above (which uses Python 2.5 syntax in which the yield call can > return a value), the sequence happens like so: > > 1. func() is entered; remote is an RPC Channel > 2. The 'foo' RPC call is marshaled and queued for delivery to the > remote end. remote.rpc() returns an InProgress, which is > yielded by the coroutine func(). > 3. The coroutine is resumed once the rpc 'foo' completes. > 4. Now the 'bar' RPC call is marshaled and queued for delivery to > the remote end. The coroutine func() yields the InProgress for > this new rpc call. > 5. The coroutine is resumed once the rpc 'bar' completes. The > result of that rpc is "returned" into the coroutine via the > yield, which is assigned to the result variable. > 6. We yield the result value from the coroutine, thereby finishing > the coroutine. > > The last two lines could be written as: > > yield (yield remote.rpc('bar')) > > But it is probably best to leave it as two separate lines because it's > more readable. > > > >> of coroutines. It is quite tricky to find suitable places in freevo-1 >> that make a difference to the application. I had to remove one of the >> few callback methods in the tvguide as it was making the guide behave badly. > > Part of that may be that you don't have an intuitive grasp on coroutines > yet, so it's not really clear at all where you could use them. A second > reason is that if you design your application to use signals and > callbacks from the start, coroutines don't really fit in very well. > Think of coroutines as an alternative approach to a sequence of signals > and callbacks. > > >>> Whenever you yield a non-InProgress result from a coroutine, the >>> coroutine is finished with that result and never reentered. >> >> I'm not 100% sure that I get this. Do you mean yielding anything other >> than the in-progress object causes the coroutine to finish there (like a >> return in a method)? > > That's right. One further exception to that rule is kaa.NotFinished, > which is a simple way for you to basically time slice a coroutine. > Think of it as cooperative multitasking. > > This is documented at https://urandom.ca/~tack/kaa/async/coroutines.html > > >> I'll read through this as it has changed since the earlier versions of >> the kaa.async package. > > Quite a bit, yeah. > > >> What would be nice is an example of coroutines in action that shows why >> someone would want to use them over threads or synchronous code. > > In the above URL I try to explain some of the reasons you would use > coroutines. I provide an example of connecting to a socket and fetching > a web page using a single coroutine: > > @kaa.coroutine() > def fetch_page(host): > """ > Fetches / from the given host on port 80. > """ > socket = kaa.Socket() > # Socket.connect() is implemented as a thread > yield socket.connect((host, 80)) > # Socket.read() and write() are implemented as single-thread > async I/O. > yield socket.write('GET / HTTP/1.1\n\n') > print (yield socket.read()) > > But to drive the point home, I should also provide the code that does > the same thing only _without_ a coroutine, by using callbacks and > connecting to each step: > > def fetch_page(host): > socket = kaa.Socket() > socket.connect((host, 80)).connect(finished_connect, socket) > > def finished_connect(result, socket): > socket.write('GET / HTTP/1.1\n\n').connect(finished_write, socket) > > def finished_write(len, socket): > socket.read().connect(finished_read) > > def finished_read(data): > print data > > > The above is functionally equivalent to the coroutine. But you can see > which code is easier to follow. > > Hope that helps,
Thanks Jason, it does help. I was under the impression that coroutines were mainly used for cooperative multitasking and doing things in the background where the result of the calls were not important. Duncan ------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com _______________________________________________ Freevo-devel mailing list Freevo-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freevo-devel