August'24: Kamaelia is in maintenance mode and will recieve periodic updates, about twice a year, primarily targeted around Python 3 and ecosystem compatibility. PRs are always welcome. Latest Release: 1.14.32 (2024/3/24)
The Graphline component wires up a set of components and encapsulates them as a single component. They are wired up to each other using the 'graph' of linkages that you specify.
Joining a PromtedFileReader and a rate control component to make a file reader that reads at a given rate:
return Graphline(RC = ByteRate_RequestControl(**rateargs),
RFA = PromptedFileReader(filename, readmode),
linkages = { ("RC", "outbox") : ("RFA", "inbox"),
("RFA", "outbox") : ("self", "outbox"),
("RFA", "signal") : ("RC", "control"),
("RC", "signal") : ("self", "signal"),
("self", "control") : ("RFA", "control")
}
The references to 'self' create linkages that passes through a named inbox on the graphline to a named inbox of one of the child components. Similarly a child's outbox is pass-through to a named outbox on the graphline.
In this example:
As a result, this example creates 3 components inside a graphline that wait for shutdown. The Pinger sends a message, which is duplicated to all the subcomponents, at which point in time, they shutdown, causing the system to shutdown:
Pipeline(
Pinger(tosend=[Axon.Ipc.producerFinished()],box="signal"),
Graphline(
TO_SHUTDOWN1 = Waiter(),
TO_SHUTDOWN2 = Waiter(),
TO_SHUTDOWN3 = Waiter(),
linkages = {}
),
Whinger(),
).run()
Note: the shutdown message propogates all the way through the system to the whinger, which then also shuts down.
Full code for this is in ./Examples/UsingChassis/Graphline/DemoShutdown.py
You can also still have shutdown links between components. If you do, then the Graphline doesn't interfere with them:
Pipeline(
Pinger(tosend=[Axon.Ipc.producerFinished()],box="signal"),
Graphline(
TO_SHUTDOWN1 = Waiter(),
TO_SHUTDOWN2 = Waiter(),
TO_SHUTDOWN3 = Waiter(),
linkages = {
("TO_SHUTDOWN1","signal"):("TO_SHUTDOWN2","control"),
("TO_SHUTDOWN2","signal"):("TO_SHUTDOWN3","control"),
}
),
Whinger(),
).run()
Full code for this is in ./Examples/UsingChassis/Graphline/LinkedShutdown.py
A Graphline component gives you a way of wiring up a system of components and then encapsulating th ewhole as a single component, with its own inboxes and outboxes.
The components you specify are registered as children of the Graphline component. When you activate the component, all the child components are activated, and the linkages you specified are created between them.
When specifying linkages, the component 'name' is the string version of the argument name you used to refer to the component. In the example above, the components are therefore referred to as "RC" and "RFA".
If the name you specify is not one of the components you specify, then it is assumed you must be referring to the Graphline component itself. In the above example, "self" is used to make this clear. This gives you a way of passing data in and out of the system of components you have specified.
In these cases, it is assumed you wish to create a pass-through linkage - you want the Graphline component to forward the named inbox to a child's inbox, or to forward a child's outbox to a named outbox of the Graphline. For example:
Graphline( child = MyComponent(...),
linkages = { ...
("self", "inbox") : ("child", "bar"),
... }
)
... is interpreted as meaning you want to forward the "inbox" inbox of the Graphline to the "bar" inbox of the component referred to as "child". Similarly:
Graphline( child = MyComponent(...),
linkages = { ...
("child", "fwibble") : ("self", "outbox"),
... }
)
...is interpreted as wishing to forward the "fwibble" outbox of the component referred to as "child" to the "outbox" outbox of the Graphline component.
Any inbox or outbox you name on the Graphline component is created if it does not already exist. For example, you might want the Graphline to have a "video" and an "audio" inbox:
Graphline( videoHandler = MyVideoComponent(),
audioHandler = MyAudioComponent(),
linkages = { ...
("self", "video") : ("videoHandler", "inbox"),
("self", "audio") : ("audioHandler", "inbox"),
...
}
)
The Graphline component will always have inboxes "inbox" and "control" and outboxes "outbox" and "signal", even if you do not specify any linkages to them.
During runtime, the Graphline component monitors the child components. It will terminate if, and only if, all the child components have also terminated.
NOTE that if your child components create additional components themselves, the Graphline component will not know about them. It only monitors the components it was originally told about.
Graphline does not GENERALLY intercept any of its inboxes or outboxes. It ignores whatever traffic flows through them. If you have specified linkages from them to components inside the graphline, then the data automatically flows to/from them as you specified.
There is however an exception: shutdown handling, where the difference is light touch, which is this:
while not self.childrenDone():
always pass on messages from our control to appropriate sub-component's control
if message is shutdown, set shutdown flag
# then after loop
if no component-has-linkage-to-graphline's signal
if shutdown flag set:
pass on shutdownMicroprocess
else:
pass on producerFinished
If the user has wired up the graphline's control box to pass through to one of their components, then that request is honoured, and the user then becomes wholly responsible for shutdown.
Tests passed:
Graphline(linkages,**components) -> new Graphline component
Encapsulates the specified set of components and wires them up with the specified linkages.
Keyword arguments:
Warning!
You should be using the inbox/outbox interface, not these methods (except construction). This documentation is designed as a roadmap as to their functionalilty for maintainers and new component developers.
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
Adds to self.Inboxes and self.Outboxes any postboxes mentioned in self.layout that don't yet exist
Unplugs any children that have terminated, and returns true if there are no running child components left (ie. their microproceses have finished)
Main loop.
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, 05 Jun 2009 at 03:01:38 UTC/GMT