Module: cogen
This is a library for network oriented, coroutine based programming. The interfaces and events/operations aim to mimic some of the regular thread and socket features.
cogen uses the enhanced generators in python 2.5. These generators are bidirectional: they allow to pass values in and out of the generator. The whole framework is based on this.
The generator yields a Operation instance and will receive the result from that yield when the operation is ready.
Roughly the cogen internals works like this:
+------------------------+
| @coroutine |
| def foo(): |
| ... | op.process(sched, coro)
| +->result = yield op--|----------------+------------+
| | ... | | |
+--|---------------------+ +---------------+ +---------------------+
| | the operation | | the operation can't |
result = op.finalize() | is ready | | complete right now |
| +------|--------+ +----------|----------+
scheduler runs foo | |
| | |
foo gets in the active | |
coroutines queue | |
| | |
+----------------------<----------+ |
| depening on the op
op.run() +---------+
| socket is ready add it in | |
+-------------<------------ ...... the reactor <--+ |
| later |
+------<------------------- ...... add it in some other <-+
some event decides queue for later run
this op is ready
The scheduler basicaly does 3 things:
- runs active (coroutine,operations) pairs (calls process on the op)
- runs the reactor
- checks for timeouts
The reactor basicaly does 2 things:
- calls the system to check what descriptors are ready
- runs the operations that have ready descriptors
The operation does most of the work (via the process, finalize, cleanup,
run methods):
- adds itself in the reactor (if it's a socket operation)
- adds itself in some structure to be activated later by some other event
- adds itself and the coro in the scheduler's active coroutines queue
The coroutine decorator wrappes foo in a Coroutine class that does some
niceties like exception handling, getting the result from finalize() etc.