Message Subsystem

Last Updated 5/24/99 - Jack Harich

This covers the first iteration. This document presents only a summary of this subsystem. This allows easy, fast comprehension. Here's the Second Iteration Design.


Nutshell Vision

Provide a single, simple, flexibile mechanism for objects to achieve Anonymous Collaboration.


Narrative

Anonymous Collaboration is things working together without knowing who the other things are. It gives a system very loose coupling, allowing higher extensibility and reuse. It requires a mediator to establish collaboration paths. It also requires something to pass back and forth, rather than traditional direct method calls with custom arguments. Thus we need a standardized football and a way to pass it around.

A Message is that football. It has an ID which for simplicity we call the message name, such as "FileOpened", "AcquireUserSecurityLevel" or "ValidateOrderForm". Many Messages have only a name. Others have key values, such as "FileName", "Level" or "NameField". The key must be a String, but the value can be anything. To reduce tight coupling, most values should be primitives, Strings or Datatrons, not custom objects.

Messages are sent from a MessageSource to zero or more MessageListeners. These interfaces can be implemented by any class. Listeners listen for just the Message names they're interested in. When a Message is sent, it only goes to listeners interested in that Message name. To make this easier to implement, sources use a MessageRouter to add listeners to and to send Messages.

A MessageDef defines the structure of a Message, such as its name and properties. This is used for inspecting a system to understand what its Messages do. It can also be used to understand a reusable class. In advanced design it can be used for tricky routing, trader style work, automatic translation, Message stream filtering, etc, although the original intent was only for inspection and validation.

There are additional subsytem classes, but these are minor.


Use Cases

1. Send a Message to listeners.

  1. Create the Message, which must have a name.
  2. Optionally add key values to the Message.
  3. Send the Message.
  4. Optionally get values out of the Message if an "Acquire" type Message.

2. Subscribe a listener to a source.

  1. Find the listener, Mesage name and source.
  2. Call a method on the source to add the listener for that Message name.

3. Unsubscribe a listener from a source.

  1. Find the listener, Mesage name and source.
  2. Call a method on the source to remove the listener for that Message name.

4. Inspect the Message structure of a system. (more to come related to this)

  1. Select a source or listener.
  2. View the "Message chains" involved.
  3. Navigate easily to surf that chain. (not yet implemented)

5. Validate the Message structure integrity of a system. (not yet implemented)

  1. Select the system, object or Message to validate.
  2. Start the validation.
  3. View the results.
  4. Take action as appropriate.


Trait List

1. Handle nearly all Anonymouse Collaboration needs. The exception is when speed is needed. For this we allows direct method calls.

2. Be verifyable. This is similar to the dependency checking a compiler does. Once we have mature Visual Tools, they can verify system integrity as you go.

3. Be fast. Messages essentially replace method calls. Object creation and use of a MessageRouter is much slower than a method call. For speed a source can reuse Messages. We may also introduce a "direct Message link" mechanism.

4. Be simple. This is achieved by a mere 3 main classes with very few methods - Message, MessageSource and MessageListener, plus support classes such as MessageDef and MessageRouter. Other subsystem classes are optional.


Risk Management

1. Inextensible. Resolved by the 3 main classes which are totally domain independent, allow carrying anything, and allow querying for needs. As far as we can tell, anything a method call can do can be done with Messages, including throwing exceptions.

2. Too slow for certain domain types. No way around this, since the Message mechanism is a trade off between the speed of method calls versus the loose coupling of Messages. Resolved by allowing alternate ways for collaboration.

3. Leads to systems that are hard to understand. Resolved by allowing querying for inspection.

4. Leads to systems full of broken dependencies. Resolved by allowing querying for validation.


Models