Using a Circuit Metaphor

7 views
Skip to first unread message

Nat Pryce

unread,
Jun 28, 2010, 5:50:24 PM6/28/10
to software...@googlegroups.com
Our current project has some awkward concurrency constraints. We're
using a proprietary library that is not thread safe, receive high-
volume market data feeds through vendor APIs that call into our code
from their own threads, and have to look up data from slow services
without delaying the processing of unrelated market data events.

We've adopted an architectural style inspired by the Conic programming
language. A Conic program is organised as lightweight processes (known
as "task modules") that communicate by message passing. Unlike the
Actor model, used by Erlang, a process cannot send a message directly
to another process. Instead, a process has output ports through which
it can send messages and input ports through which it can receive
messages. The interface of a component is defined as a set of named,
typed input & output ports. A program is constructed by instantiating
modules and linking their output ports to the input ports of other
modules. You can also define new "group module" types this way: by
instantiating submodules, connecting them together and exposing some
of their ports at the interface of the group module. From outside,
there's no way to know if a module is a primitive task module or a
composite group module.

Conic's model imposes some constraints to achieve simplicity at the
architectural level. A major constraint is that a group module has no
behaviour of its own: its behaviour is only defined by the composition
of sub-modules within it and the ports of its sub-modules it exposes
at its interface. That constraint brings a lot of benefits. It gives
you a conceptual framework with which to decompose complex concurrent
behaviour into composable event-driven pieces that are easy to test
(or even model check), grok the architecture from the configuration
code that defines the system and generate visualisations with graphviz.

In Conic this constraint is enforced by the language. Separate
languages are used to define task modules and compose them into group
modules. However, our system is written in Java. There's nothing in
the language to stop programmers adding behaviour to group modules and
violating the model. We must adhere to the architectural style through
convention.

The constraints imposed by the style are not really obvious from the
terminology used by Conic ("task module", "group module", "link").
When I was introduced to Conic, the style was described to me as
"software integrated circuits", so I've used a circuit metaphor in the
Java implementation to better express the important constraints. We
define "components", rather than "modules", and compose components
into "circuits" rather than "group modules". A circuit "connects",
rather than "links", outputs to inputs. We plan to add support for
"wiretaps" or "signal analysers" to monitor the flow of messages
between components for support & performance measurements.

We have recently found the need for circuit types that represent only
interconnections, into which different concrete types of component can
be plugged, as long as they conform to a compatible abstract
interface. I suggested the name "PCB" for these, but I think that was
one metaphor too far for the rest of the team and the suggestion was
rejected. For now!

--Nat

www.natpryce.com

Reply all
Reply to author
Forward
0 new messages