Kamaelia docs : Axon.experimental._pprocess_support

likefile - file-like interaction with components

likefile is a way to run Axon components with code that is not Axon-aware. It does this by running the scheduler and all associated microprocesses in a separate thread, and using a custom component to communicate if so desired.

Using this code

With a normal kamaelia system, you would start up a component and start running the Axon scheduler as follows, either:

from Axon.Scheduler import scheduler

or simply:


In both cases, someOtherCode() only run when the scheduler exits. What do you do if you want to (e.g.) run this alongside another external library that has the same requirement?

Well, first we start the Axon scheduler in the background as follows:

from likefile import background

The scheduler is now actively running in the background, and you can start components on it from the foreground, in the same way as you would from inside kamaelia (don't worry, activate() is threadsafe):


"component" will immediately start running and processing. This is fine if it's something non-interactive like a TCP server, but what do we do if we want to interact with this component from someOtherCode?

In this case, we use 'likefile', instead of activating. This is a wrapper which sits around a component and provides a threadsafe way to interact with it, whilst it is running in the backgrounded scheduler:

from Axon.LikeFile import likefile
wrappedComponent = likefile(component)

Now, wrappedComponent is an instance of the likefile wrapper, and you can interact with "component" by calling get() on wrappedComponent, to get data from the outbox on "component", or by calling put(data) to put "data" into the inbox of "component" like so:

p = likefile( SimpleHTTPClient() )
google = p.get()
print "google's homepage is", len(google), "bytes long.

for both get() and put(), there is an optional extra parameter boxname, allowing you to interact with different boxes, for example to send a message with the text "RELOAD" to a component's control inbox, you would do:

wrappedComponent.put("RELOAD", "control")

Finally, likefile objects have a shutdown() method that sends the usual Axon IPC shutdown messages to a wrapped component, and prevents further IO.

Advanced likefile usage

likefile has some optional extra arguments on creation, for handling custom boxes outside the "basic 4". For example, to wrap a component with inboxes called "secondary" and "tertiary" and an outbox called "debug", You would do:

p = likefile( componentMaker,
              extraInboxes = ("secondary", "tertiary"),
              extraOutboxes = "debug", )

Either strings or tuples of strings will work.

It may be the case that the component you are trying to wrap will link its own inbox/outbox/signal/control, and this will result in a BoxAlreadyLinkedToDestination exception. To stop likefile from wrapping the default 4 boxes, pass the parameter wrapDefault = False. Note that you will need to manually wrap every box you want to use, for example to wrap a component that has its own linkages for signal/control:

p = likefile( myComponent,
              wrapDefault = False,
              extraInboxes = "inbox",
              extraOutboxes = "outbox", )

Diagram of likefile's functionality

likefile is constructed from components like so:

     |             likefile             |
          |                      / \
          |                       |
      InQueues                 OutQueues
          |                       |
|        \ /                      |         |
|    +---------+               +--------+   |
|    |  Input  |   Shutdown    | Output |   |
|    | Wrapper | ------------> |        |   |
|    | (thread)|   Message     |Wrapper |   |
|    +---------+               +--------+   |
|         |                      / \        |
|         |                       |         |
|     Inboxes                 Outboxes      |
|         |                       |         |
|        \ /                      |         |
|    +----------------------------------+   |
|    |      the wrapped component       |   |
|    +----------------------------------+   |
|                                           |
|    +----------------------------------+   |
|    |       Some other component       |   |
|    |     that was only activated      |   |
|    +----------------------------------+   |
|                                           |

Note 1: Threadsafeness of activate().

when a component is activated, it calls the method inherited from microprocess, which calls _addThread(self) on an appropriate scheduler. _addThread calls wakeThread, which places the request on a threadsafe queue.


addBox(names, boxMap, addBox)

Add an extra wrapped box called name, using the addBox function provided (either self.addInbox or self.addOutbox), and adding it to the box mapping which is used to coordinate message routing within component wrappers.


class background(threading.Thread)

A python thread which runs a scheduler. Takes the same arguments at creation that scheduler.run.runThreads accepts.


class componentWrapperInput(Axon.ThreadedComponent.threadedadaptivecommscomponent)

A wrapper that takes a child component and waits on an event from the foreground, to signal that there is queued data to be placed on the child's inboxes.

Methods defined here

pollQueue(self, whatInbox)

This method checks all the queues from the outside world, and forwards any waiting data to the child component. Returns False if we propogated a shutdown signal, true otherwise.

Methods inherited from Axon.ThreadedComponent.threadedadaptivecommscomponent :

Methods inherited from Axon.ThreadedComponent.threadedcomponent :

Methods inherited from Axon.Component.component :

Methods inherited from Axon.Microprocess.microprocess :

Methods inherited from Axon.AdaptiveCommsComponent._AdaptiveCommsable :


class componentWrapperOutput(Axon.AdaptiveCommsComponent.AdaptiveCommsComponent)

A component which takes a child component and connects its outboxes to queues, which communicate with the likefile component.

Methods defined here


This method will take any outgoing data sent to us from a child component and stick it on a queue to the outside world.

Methods inherited from Axon.Component.component :

Methods inherited from Axon.Microprocess.microprocess :

Methods inherited from Axon.AdaptiveCommsComponent._AdaptiveCommsable :


class dummyComponent(Axon.Component.component)

A dummy component. Functionality: None. Prevents the scheduler from dying immediately.

Methods defined here

Methods inherited from Axon.Component.component :

Methods inherited from Axon.Microprocess.microprocess :


class likefile(object)

An interface to the message queues from a wrapped component, which is activated on a backgrounded scheduler.

Methods defined here

empty(self[, boxname])

Return True if there is no data pending collection on boxname, False otherwise.

get(self[, boxname][, blocking][, timeout])

Performs a blocking read on the queue corresponding to the named outbox on the wrapped component. raises AttributeError if the likefile is not alive. Optional parameters blocking and timeout function the same way as in Queue objects, since that is what's used under the surface.

get_nowait(self[, boxname])

Equivalent to get(boxname, False)

put(self, msg[, boxname])

Places an object on a queue which will be directed to a named inbox on the wrapped component.

qsize(self[, boxname])

Returns the approximate number of pending data items awaiting collection from boxname. Will never be smaller than the actual amount.


Sends terminatory signals to the wrapped component, and shut down the componentWrapper. will warn if the shutdown took too long to confirm in action.


Got a problem with the documentation? Something unclear that could be clearer? Want to help improve it? Constructive criticism is very welcome - especially if you can suggest a better rewording!

Please leave you feedback here in reply to the documentation thread in the Kamaelia blog.

-- Automatic documentation generator, 01 Feb 2010 at 04:00:28 UTC/GMT


Kamaelia is an open source project originated from and guided by BBC Research. For more information browse the site or get in contact.

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

This web site is powered by the same code created for the bicker manor project. For more details, contact Michael Sparks at BBC Research directly (cf contact)