All Packages Class Hierarchy This Package Previous Next Index
A message chain may run from PartA to Router1 to PartB and PartC, PartA to Router1 to Router2 to PartB, etc. Each container (aka cell) has a MessageRouter, allowing parts to send Messages anywhere in the system along these message chains. These chains are created by connections of part signals (from MessageSenders) to MessageRouters and interests (from MessageReceivers) from MessageRouters.
Think of a part as having a "pin" like a computer chip for each message name. A connection connects that pin to the MessageRouter. Thereafter the part can send or receive messages along that connection, because the router knows about the connection.
Connection types resolve the "same Message name endless loop" problem and allow crystal clear definition of a system's message circuits. Ultimately they allow a precise message chain between any two parts in a system. Here's a diagram explaining this.

One thing to understand is once a message is sent outside a cell, only its nameis used for routing. Thus if PartA and PartB in a cell send a message with the same name, there's no way to route one message from PartA to PartC outside the cell and the other message from PartB to PartD outside the cell. This may seem odd at first, but it greatly simplifies system circuitry. It also allows a cell part to publish what it sends and accepts without reference to its internal parts. This allows a group of assembled parts to appear as one part, the cell, which can be reused like any other part.
// Connection types for messages from parts in the router's cell int SIGNAL_OUT int SIGNAL_IN int SERVICE_NEED // // Connection types for messages to parts in the router's cell int INTEREST_OUT int INTEREST_IN int SERVICE_SUPPLIER // // For direct part to part connections int DIRECT // // Connection creation and removal void connect(Connection connection); void disconnect(Connection connection); // // Called by parts within the cell with this router int sendMessage (Message message, MessageSender sender); // // Called by routers in cells below this router int serviceMessage(Message message, MessageSender sender); // // Miscellaneous properties void setParentRouter(MessageRouter parentRouter); MessageRouter getParentRouter(); // // We also have many getters for tools, or may use a separate Info // object. This is under design. Examples from generation one are: Enumeration getMessageNames(); Enumeration getMessageReceivers(String messageName); Enumeration getMessageNamesWithReceiver(MessageReceiver receiver);
sendMessage(...) works.
A Message Service is a single Message name handled by a MessageReceiver part for many MessageSender parts in many subcells. This provides the Service Architecture Pattern. A part can receive both normal and service Messages. A part never knows whether it's being used as a service or not.
The exact Message Service policy is:
1. A MessageReceiver should not know if it's being used as a service or not. This allows greater reuse.The implementation has documentation for some responsibilities that are not covered in the interface, such as Messages sent and received.2. There can be only a single Message Service for a message name in a cell.
3. The "automatic upward search" stops when at least one receiver registered for that Message name is found. Note we don't try to use a return value from
receive(Message)to determine whether the message has been handled, but the fact that the part was registered to handle it. This prevents confusing system designs. Service messages need clear destinations.4. If a Message Service part needs to not service the Message, it should act as a filter and send the Message on. This lifts that responsibility from the router, who only has registry and explicit static routing responsibilities.
TODO - Later this interface will extend MessageReceiverDefiner and MessageSenderDefiner. We have not yet figured out how to best publish message service signals and interests. We expect this interface to evolve. :-)
connect(Connection).
public abstract void connect(Connection connection)
public abstract Connection disconnect(Connection connection)
connect(Connection).
public abstract void sendMessage(Message message,
MessageSender sender,
String partName)
This method is called by the MessageDispatcher. Each part in a cell that's a MessageSender has a MessageDisplatcher. Thus this method contains messages only from parts inside the cell. These are hooked up with SIGNAL_OUT, SIGNAL_IN, SERVICE_OUT or DIRECT.
Here's the unfortunately complex and subtle algorithm for this method:
1. Internally determine the connections existing for the message name and sender. Put the results in isSignalOut, isSignalIn, isServiceNeed and isDirect.2. If isSignalOut is true, call my receiver, as set in my
setMessageReceiver(MessageReceiver)method.3. If isSignalIn is true, call all receivers connected with INTEREST_IN for the message name.
4. If isDirect is true, call the receivers connected with DIRECT for the message name from that sender.
5. If isServiceNeed is true:
- If this router has a SERVICE_SUPPLIER for the message name, call that receiver.6. If monitoring is turned on, just before and after each message is sent, messages named "MonitorBeforeReceive" and "MonitorAfterReceive" are sent to this very method. Endless loops are avoided by not sending monitor messages for these two message names. Monitoring is an unusual message case. :-)- Otherwise if the parent router is not null, call parentRouter.serviceMessage(message, sender);
- Otherwise there is no one to handle the service needed, so a RuntimeException is thrown since this is a probable configuration error. Parts are welcome to catch this exception if they consider message fulfillment optional.
public abstract void serviceMessage(Message message,
MessageSender sender)
sendMessage(...)
public abstract void setParentRouter(MessageRouter parentRouter)
public abstract MessageRouter getParentRouter()
public abstract Enumeration getMessageNames()
public abstract Enumeration getMessageReceivers(String messageName)
public abstract Enumeration getMessageNamesWithReceiver(MessageReceiver receiver)
All Packages Class Hierarchy This Package Previous Next Index