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.
Modules
common
A module for quick importing the essential core stuff. (coroutine, Scheduler, events, sockets, priority)
core
This module holds the essential stuff.
Programming with this library should be straghtforward. A coroutine is just a generator wrapped in a operation handling class:
@coroutine def mycoro(bla): yield <operation> yield <operation>
- the operation instructs the scheduler what to do with the coroutine: suspend it till someting happens, add another coro in the scheduler, raise a event and so on.
- the operations are split up in 2 modules: events and sockets
- the operations from sockets are related to network, like reading and writing, and these are done asynchronously but your code in the coroutine will see them as a regular synchronous or blocking call.
- the operations from events are related to signals and coroutine/scheduler management.
- if a operation has a result associated then the yield will return that result (eg. a string or a (connection, address) tuple) otherwise it will return the operation instance.
Typical example:
import sys, os from cogen.common import * @coroutine def server(): srv = sockets.Socket() srv.setblocking(0) srv.bind(('localhost',777)) srv.listen(10) while 1: print "Listening..." conn, addr = yield sockets.Accept(srv) print "Connection from %s:%s" % addr m.add(handler, conn, addr) @coroutine def handler(sock, addr): yield sockets.Write(sock, "WELCOME TO ECHO SERVER !\r\n") while 1: line = yield sockets.ReadLine(sock, 8192) if line.strip() == 'exit': yield sockets.Write(sock, "GOOD BYE") sock.close() return yield sockets.Write(sock, line) m = Scheduler() m.add(server) m.run()
web
This module holds a wsgi server and future web-related code.