Axon Component HandlesThe purpose behind Axon.Handle's is to allow the use of Kamaelia based components and systems in non-Kamaelia systems, in a relatively intuitive way.
The name Handle derives from the concept of a file-handle. We dropped the name "LikeFile" since whilst it derives from the concept of a file handle, it doesn't use the same API as file() for some good reasons we'll come back to.
A file handle is an opaque thing that you can .write() data to, and .read() data from. This is a very simple concept and belies a huge amount of parallel activity happening concurrently to your application. The file system is taking your data and typically buffering it into blocks. Those blocks then may need padding, and depending on the file system, may actually be written immediately to the end of a cyclone buffer in a journal with some write operations. Then periodically those buffers get flushed to the actual disk.Based on the fact that file handles are a very natural thing for people to work with, based on their ubiquity, and the fact that it masks the fact you're accessing a concurrent system from a linear one, that's why we've taken this approach for integrating Kamaelia components (which are naturally parallel) with non-Kamaelia code, which is typically not parallel.
For simplicity of implementation, initially the implementation of Handle supports only the equivalent of non-blocking file handles. This has two implications:
Running the Axon Scheduler in the BackgroundClearly for this to work, Kamaelia's core - Axon - needs a way of running components in the background. ie a way of putting the scheduler in the background. This is actually pretty trivial, and can be used in a very basic way (say, to run an Echo Protocol server in the background) like this:
As should be clear from this, the scheduler is started in the background, the server is activated and then system sits waiting for people to connect whilst periodically going "Ptang!"from Axon.background import background
We'll use the following component in our examples below:
Now, clearly this is a simple component, but it be anything. If could for example be a component that forwards each line to translate.google.com or babelfish.av.com, to translate the provided words into a different language. The usage would still be the same - messages coming in inbox "inbox", and transformed data coming out outbox "outbox".class Reverser(Axon.Component.component):
UsageGiven the example component above, we decide to manually feed it the contents of stdin.
First of all we need our imports:
from Axon.Handle import Handlefrom Axon.background import backgroundimport Queue
Queue is needed because currently the exceptions thrown by Handle (when the Handle isn't ready) are from that module.
Start the scheduler in the background:
Start our Reverser component in the background, inside a Handle:
reverser = Handle(Reverser()).activate()
The it's just a matter of using it:
What should be clear here is that we feed data into the reverser using the .put() method.
The reason why we don't use a file-like object here also becomes clear : 1) unlike read()/write() we have multiple possible destinations for the data - "inbox", "control", and we also have multiple sources of data "outbox", "signal". 2) Also, rather than shipping over binary data, we're passing over arbitrary python objects. Whilst in this case this happens to be strings it could be anything from simple records in dictionaries through to video data.
Other ExamplesOther examples are in the Axon distribution and also in the Kamaelia Distribution. These can be browsed online here:
This is an ongoing community based development site. As a result the contents of this page is the opinions of the contributors of the pages involved not the organisations involved. Specificially, this page may contain personal views which are not the views of the BBC. (the site is powered by a wiki engine)
(C) Copyright 2008 Kamaelia Contributors, including the British Broadcasting Corporation, All Rights Reserved