The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
		       Stem Message Design Notes

Stem Messages are how Cells communicate with each other. Messages are
simple data structures with two major sections: the address and the
content. The address contains the Cell name the message is directed to and
which Cell to send replies to. The content has the message type, command
and data. These sections are described below in further detail.

The Message address section has multiple addresses called types. The two
supported types correspond to the common email headers and are called
'to' and 'from'. The 'to' address designates which Cell will get this
message and the 'from' address says which Cell sent this message. Other
address types which may be supported are 'reply' (which overrides the
'from' address for replies) and 'orig' which is the address of the
original Cell which created this message (useful when messages get
forwarded).  Each address type contains the standard Stem Cell address
triplet of Hub/Cell/Target which are called the address parts. The Cell
name is required and the Hub and Target are optional.

The Message content has information about this message and any data
being sent to the destination Cell. The primary attribute is 'type'
which can be set to any string, but common types are 'data', 'cmd',
'response' and 'status'. Stem modules and Cells can create any Message
types they want. If the Message is a 'cmd' type, then the 'cmd'
attribute must be set to the command. A status type Message requires the
'status' attribute be set and the 'data' or 'response' types has the
'data' attribute set (though any message type can send data). There is
also a special flag attribute called 'ack_req' which forces a 'msg_ack'
type to be sent back to the 'from' address after this message is
delivered. One important note about the 'data' attribute, it is always a
reference and never a simple Perl scalar value. You can send a scalar
value but only by setting the 'data' attribute to its reference.

Messages are constructed with the 'new' method of the Stem::Msg
class. Any of the message attributes can be specified in that call or
accessed/modified with the accessor methods. When a Message is completed
and ready to be sent, the dispatch method is called and the message is
queued for delivery. For convenience, the Message address types and part
can be combined into one attribute name in both the constructor and
accessors. So the Cell the message is directed at can be set with
'to_cell' and the Hub it came from can be accessed with 'from_hub'. The
entire address triplet of an address type can be set or accessed just
with its type name, so the 'to' address is set or accessed with the 'to'
attribute or method. It takes or returns a hash of the address parts and
their values.

Messages are delivered only after the current callback is finished
executing (remember all code in Stem are called as callbacks). Stem
Message delivery is the heart of Stem operations and is described in
detail here. Delivery take place in three phases, the first determining
which Hub the Message is sent to, the second, which Cell in that Hub
gets it, and the third, which method in that Cell to call for delivery.

If the Message has a 'to_hub' address, then that Hub name is looked up
in the Portal (which are Cells which connect Hubs together) registry. If
a Portal is found, the Message is delivered to it to be sent to the
destination Hub for local delivery. A Message can be forwarded across
several Hubs before it gets delivered to its destination Cell. If the
Hub name is the same as the current Hub or there is no Hub name in the
address, the Message is delivered to a Cell in the current Hub. In the
special case where there is no Hub name and the Cell name isn't
registered in the current Hub, the Message is sent to the Portal with an
alias of DEFAULT. This is just like the default route in IP routing
tables. If there is a Hub name and the Cell is not found, then there is
an addressing error and that is logged and the Message is discarded.

Once a Message's destination Hub is reached, it must be delivered to a
local Cell. The 'to_cell' and 'to_target' attributes are accessed from
the message and that pair is searched for in this Hub's Cell registry.
If there is no Target name in the address, it defaults to the null
string.  If there is a Target and the Cell is not found, the search is
repeated with no Target name (the Target name will be used by the
destination Cell). If the Cell still is not found, an addressing error
will be logged (with the message address) and the Message is discarded.

When the destination Cell of a Message is determined, the method to call
for delivery must be chosen. The rules for this are simple. If a Message
is a 'cmd' type, then the method name is made by taking the 'cmd' name
from that attribute and appending '_cmd' to it. So a 'foo' command
message will have its type set to 'cmd', the 'cmd' set to 'foo' and it
will be delivered to the 'foo_cmd' method. If the Message is any other
type than 'cmd' the method name is created by taking its type name and
appending '_in' to it. So a 'foo' type Message is delivered to the
method 'foo_in'. If the delivery method doesn't exist, the default
method 'msg_in' is used. If no delivery method is found, then an error
is logged and the Message is discarded.

Command Messages have a useful feature where they can automatically
generate 'response' messages. When a 'cmd' delivery method is called and
it returns a defined value, a 'response' type Message is created using
the 'reply' Message method. This uses the 'reply' or 'from' address in
'cmd' Message as the 'to' address in the 'response' Message. Its data
field is set from the data returned from the command delivery
method. This reduces the work of common command methods to just having
to return a data value. Many Cells use this technique, e.g.  the
status_cmd method in a Cell just returns the status text of it. The
delivery mechanism takes that text and creates and dispatches a
'response' method with the status text as its 'data' payload.