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, Jason. ------------------------------------------------------------------------------ _______________________________________________ Freevo-devel mailing list Freevo-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freevo-devel