Part of kiwi
Pseudo-thread (coroutines) framework
This module adds infrastructure for managing tasklets. In this context, a tasklet is defined as a routine that explicitly gives back control to the main program a certain points in the code, while waiting for certain events. Other terms that may be used to describe tasklets include coroutines, or cooperative threads.
The main advantages of tasklets are:
The fundamental block used to create tasklets is Python's generators.
Generators are objects that are defined as functions, and when called
produce iterators that return values defined by the body of the function,
specifically yield
statements.
The neat thing about generators are not the iterators themselves but
the fact that a function's state is completely frozen and restored
between one call to the iterator's next()
and the following
one. This allows the function to return control to a program's main loop
while waiting for an event, such as IO on a socket, thus allowing other
code to run in the mean time. When the specified event occurs, the
function regains control and continues executing as if nothing had
happened.
At the outset, a tasklet is simply a python generator
function, i.e. a function or method containing one or more
yield
statements. Tasklets add a couple more requirements
to regular generator functions:
yield
statements cannot be
arbitrary (see below);
yield
that indicates events, the function kiwi.tasklet.get_event
must be called to retrieve the event that just occurred.
Inside tasklet functions, yield
statements are used to
suspend execution of the tasklet while waiting for certain events. Valid
yield
values are:
Message
object, with a correctly set dest parameter. With this form,
a message is sent to the indicated tasklet. When yield
returns, no event is generated, so the tasklet should not call
get_event
.
WaitCondition
,
meaning to wait for that specific condition
Tasklet
,
with the same meaning as WaitForTasklet
(tasklet)
WaitForTasklet
(Tasklet(gen))
In this case, the tasklet is suspended until either one of the
indicated events occurs. The tasklet must call get_event
in this
case.
To start a tasklet, the Tasklet
constructor
must be used:
from kiwi import tasklet def my_task(x): [...] tasklet.Tasklet(my_task(x=0))
Alternatively, kiwi.tasklet.run
can be
used to the same effect:
from kiwi import tasklet tasklet.run(my_task(x=0))
Yet another approach is to use the @tasklet.task decorator:
from kiwi import tasklet @tasklet.task def my_task(x): [...] raise StopIteration("return value") yield my_task(x=0) retval = tasklet.get_event().retval
This example demonstrates basic tasklet structure and timeout events:
import gobject from kiwi import tasklet mainloop = gobject.MainLoop() def simple_counter(numbers): timeout = tasklet.WaitForTimeout(1000) for x in xrange(numbers): print x yield timeout tasklet.get_event() mainloop.quit() tasklet.run(simple_counter(10)) mainloop.run()
This example extends the previous one and demonstrates message passing:
import gobject from kiwi import tasklet mainloop = gobject.MainLoop() @tasklet.task def printer(): msgwait = tasklet.WaitForMessages(accept=("quit", "print")) while True: yield msgwait msg = tasklet.get_event() if msg.name == "quit": return assert msg.name == 'print' print ">>> ", msg.value @tasklet.task def simple_counter(numbers, task): timeout = tasklet.WaitForTimeout(1000) for x in xrange(numbers): yield tasklet.Message('print', dest=task, value=x) yield timeout tasklet.get_event() yield tasklet.Message('quit', dest=task) mainloop.quit() task = printer() simple_counter(10, task) mainloop.run()
Class | task | A decorator that modifies a tasklet function to avoid the need |
Function | get_event | Return the last event that caused the current tasklet to regain control. |
Function | run | Start running a generator as a Tasklet . |
Class | WaitCondition | Base class for all wait-able condition objects. |
Class | WaitForCall | An object that waits until it is called. |
Class | WaitForIO | An object that waits for IO conditions on sockets or file |
Class | WaitForTimeout | An object that waits for a specified ammount of time (a timeout) |
Class | WaitForIdle | An object that waits for the main loop to become idle |
Class | WaitForTasklet | An object that waits for a tasklet to complete |
Class | WaitForSignal | An object that waits for a signal emission |
Class | WaitForProcess | An object that waits for a process to end |
Class | Message | A message that can be received by or sent to a tasklet. |
Class | WaitForMessages | An object that waits for messages to arrive |
Class | Tasklet | An object that launches and manages a tasklet. |
Function | _normalize_list_argument | returns a list of strings from an argument that can be either |
Note | this function should be called exactly once after each yield that includes a wait condition. |