ANN: Axon 1.0

Discussion in 'Python' started by Michael Sparks, Dec 25, 2004.

  1. Hi,

    Axon is the core set of modules in Kamaelia[1], and is essentially a set
    of tools for managing concurrency inside a single thread. Whilst it is a
    pre-requisite for Kamaelia, it can be used independently as well.

    Rather than the usual statemachine (or state machine derived) approach it
    uses communicating generators. The design of the system is inspired very
    heavily by asynchronous hardware verification systems. (Which leads to
    similarities with CSP & unix pipelines)

    [1] Kamaelia is BBC R&D testbed for developing media network protocols.
    (It takes it's name from an internal BBC R&D project aimed at looking
    how we scale internet delivery of the BBC's TV & Radio output.)

    Sourceforge page with Axon release:

    Installation is the usual "python install" dance, and the API
    should be fairly stable, and has evolved over a period of time, hence the
    1.0 release version. The project became test infected rather late in the
    day, so some of test suite has been retrofitted if it looks a bit odd!

    Kamaelia's website:

    (Explains context and there's a presentation that contains a simplified
    implementation using decorators, which might help show use cases)

    I've copied much of the README at the end of this mail for the curious.
    (License is the Mozilla tri-license : MPL1.1, GPL2.0, LGPL2.1)

    Merry Christmas! (Hopefully someone will find this a nice christmas toy :)

    Axon is the core of Kamaelia. The contents of this directory must be
    installed before the rest of Kamaelia can be used. It can also be used
    independently of Kamaelia.

    The install procedure is python's usual dance:

    * python install

    Documentation is held in two places:
    * The usual 'pydoc name' - probably worth starting with:
    pydoc Axon.Component

    * The test suite is designed to allow you to get low level API behaviour
    information - "should X,Y, Z work? If so, what happens?". It's a partly
    retrofitted test suite, but some is TDD. (TDD took over late in the
    project) As a result, for example, passing a -v flag result in the
    docstring for each test to be dumped in a form that allows collation,
    and summarisation. (For an example of what we expect to automate from
    the test suite, see the end of this README file)

    Sample producer/consumber & wrapper component system:

    /-- testComponent -----------------------------------------------\
    | |
    | +-- Producer ----+ +-- Consumer ----+ |
    | | |result|--->|source| |result|--->|_input||
    | +----------------+ +----------------+ |
    | |

    The testComponent creates 2 subcomponents, creates the links in place, and
    takes the output from the consumer and links it to its own private/internal
    _input inbox. When it recieves a value from the consumer, it reports this
    fact and ceases operation.

    Producer sends values to its result outbox
    Consumer takes values from its source, does some work and sends results to
    its outbox

    (It's probably worth noting that an introspection system would be possible
    to write/nice to see that would be able to derive the above diagram from
    the running system)

    Example code:

    class Producer(component):
    def __init__(self):
    def main(self):
    i = 100
    i = i -1
    self.send("hello", "result")
    yield 1

    class Consumer(component):
    def __init__(self):
    self.count = 0
    self.i = 30
    def doSomething(self):
    print, "Woo",self.i
    if self.dataReady("source"):
    self.count = self.count +1
    self.send(self.count, "result")

    def main(self):
    yield 1
    self.i = self.i -1
    yield 1

    class testComponent(component):
    def __init__(self):
    self.producer = Producer()
    self.consumer = Consumer()
    self.addChildren(self.producer, self.consumer), "result"), (self.consumer, "source"))
    linkage(self.consumer,self,"result","_input", self.postoffice)

    def childComponents(self):
    return [self.producer, self.consumer]

    def mainBody(self):
    while len(self.inboxes["_input"]) < 1:
    yield 1
    result = self.recv("_input")
    print "Consumer finished with result:", result, "!"

    r = scheduler()
    p = testComponent()
    children = p.childComponents()
    for p in children:

    (It would probably be nice to have better syntactic sugar here by using
    dictionaries, operators (eg '|' ) and decorators. The presentation on the
    website on Kamaelia shows a partial semi-reimplementation of ideas using
    decorators to eliminate the classes above)

    For various reasons it makes sense to run all Axon code using the -OO flags
    - this is due to the currently highly inefficient debug framework. One
    downside of async systems is that debuggers tend to have a hard time - but
    this has been thought of upfront :), the downside is that if you run with
    debugging enabled/possible, then the system runs like a pig. (Due to some
    rather heavy duty fumbling around in the garbage collector)

    Michael, December 2004


    Example of expected autodocs from test suite:
    (Ideally these would be merged with (or replace!)the doc strings/output
    from pydoc.)

    ../ -v 2>&1 | ~/bin/

    Class constructor is expected to be called without arguments.

    Returns a string representation of the component - consisting of
    Component, representation of inboxes, representation of outboxes.
    Returns a string that contains the fact that it is a component object
    and the name of it.

    All arguments are added as child components of the component.

    Returns the list of children components of this component.

    stub method, returns 1, expected to be overridden by clients.

    Returns true if the supplied inbox has data ready for processing.

    Stub method, returns 1, expected to be overridden by clients.

    Creates a link, handled by the component's postman, that links a
    source component to it's sink, honouring passthrough, pipewidth and
    synchronous attributes.

    Returns a generator that implements the documented behaviour of a
    highly simplistic approach component statemachine.
    This ensures that the closeDownComponent method is called at the end
    of the loop. It also repeats the above test.

    stub method, returns None, expected to be overridden by clients as the
    main loop.

    Takes the first item available off the specified inbox, and returns

    Removes the specified component from the set of child components and
    deregisters it from the postoffice.

    Takes the message and places it into the specified outbox, throws
    an exception if there is no space in a synchronous outbox.

    Called with no arguments sets the outbox 'outbox' to being a
    synchronised box, with a maximum depth of 1.

    Takes a list of things to send, and returns a generator that when
    repeatedly called tries to send data over a synchronised outbox.

    Registers the component as a child of the component. Internal function.

    Always returns true. Components are microprocesses instantiated by
    users typically - thus they are creators of activity, not slaves to
    it. Internal function.

    Checks the shutdownMicroprocess message for the scheduler contains a
    reference to the postoffice associated with the component.
    Returns a shutdownMicroprocess. Internal Function.

    Takes the first piece of data in an outbox and returns it. Raises
    IndexError if empty. Internal function.

    Tests with default args. All these deliveries should suceed. Internal
    Tests with default args. Should raise IndexError as the box should be
    empty in this test. Internal Function.
    Tests with inbox arg. Should raise IndexError as the box should be
    empty in this test. Internal Function.
    Tests with inbox arg. Tests collection. Internal Function.

    Appends the given message to the given inbox. Internal Function.
    Checks delivery to a synchronised inbox fails when it is full using the
    force method.
    Checks delivery to a synchronised inbox fails when it is full.

    Appends the given message to the given inbox. Internal Function.
    Should throw noSpaceInBox if a synchronised box is full.
    When force is passed as true the box can be overfilled.

    Appends the given message to the given outbox. Internal Function.
    Checks delivery is limited to the pipewidth.
    Checks delivery is limited to the pipewidth.

    Appends messages to given outbox. Should throw noSpaceInBox when full.

    Wrapper around _collect - returns None where an IndexError would
    normally be thrown. Internall Function.
    Michael Sparks, Dec 25, 2004
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Sampson [MSFT]

    [ANN]: NNTP Server slow downs.

    Mike Sampson [MSFT], Oct 7, 2003, in forum: ASP .Net
    Mike Sampson [MSFT]
    Oct 7, 2003
  2. Mike Sampson [MSFT]

    [ANN]: NNTP Server slow downs.

    Mike Sampson [MSFT], Dec 6, 2003, in forum: ASP .Net
    Mike Sampson [MSFT]
    Dec 6, 2003
  3. Richard Grimes [MVP]

    ANN: Free .NET Workshops

    Richard Grimes [MVP], Jul 4, 2005, in forum: ASP .Net
    Richard Grimes [MVP]
    Jul 4, 2005
  4. Michael Livsey
    Michael Livsey
    May 27, 2004
  5. Michael Sparks

    ANN: Axon 1.1.0 has been released!

    Michael Sparks, Jun 4, 2005, in forum: Python
    Michael Sparks
    Jun 4, 2005
  6. Michael

    ANN: Axon 1.5.0 RELEASED!

    Michael, Jun 21, 2006, in forum: Python
    Jun 21, 2006
  7. Michael Sparks
    Michael Sparks
    Dec 10, 2007
  8. Michael Sparks
    Michael Sparks
    Dec 24, 2007