Commit | Line | Data |
4536f655 |
1 | |
2 | Stem Cell Registry and Message Address Design Notes |
3 | |
4 | The heart of Stem is the messaging subsystem and the heart of that is |
5 | the registry. This is where all knowledge of how to address cells is |
6 | located. Each cell gets registered by it name and optionally its target |
7 | and messages are directed to it via its names. The decisions made by the |
8 | registry when delivering a message are described here as well as the API |
9 | and other related issues and modules. |
10 | |
11 | |
12 | Stem Message Addresses |
13 | |
14 | Stem messages are sent to registered cells by using an address triplet: |
15 | the hub name, the cell name and the target name. |
16 | |
17 | A hub is a single process running Stem. Its name must be unique among all |
18 | Stem hubs in a single connected net. A hub consists of a set of objects |
19 | and Stem cells. It contains the message registry, the core Stem system |
20 | and it will load other modules on demand. |
21 | |
22 | A Stem cell is a single object in a Stem hub which has registered itself |
23 | under a name and can receive messages via its methods. Not all objects |
24 | in Stem are cells, but all Stem cells are objects. Cells are commonly |
25 | registered by the Stem::Config system or by a parent cell spawning |
26 | targeted cells. Only one cell can be registered in a hub for a given |
27 | cell name. One unusual trick is that a whole class can register itself |
28 | as a cell by using its class name as the object and some fixed string as |
29 | the name (sometimes that is the class name as well). There can only be |
30 | one cell by that class and name but there can be aliases for any cell |
31 | name. That is used by cells which must be implemented with class level |
32 | data. |
33 | |
34 | The target is the last part of an address and is optional. A given cell |
35 | could be registered with a cell name and target and it can send and |
36 | receive messages with its own globally unique address. The cell name is |
37 | either the parent's cell name or a fixed one for the particular class |
38 | (the Stem::Log::Filter class does this). The target name is commonly |
39 | either a Stem::Id value or a name from a configuration. Another use for |
40 | the target is a cell such as Stem::Switch which uses it to address its |
41 | input/output maps. The use of the target is defined by the design of the |
42 | cell. |
43 | |
44 | Message Delivery |
45 | |
46 | The first step in delivering a message is finding out which cell it goes |
47 | to. This is done by looking up the cell that matches the hub/name/target |
48 | address in the message. This is a multistep procedure with the following |
49 | rules: |
50 | |
51 | If the hub name of the message is set and it is not the name of this |
52 | hub, locate the portal that can send to that hub and deliver the message |
53 | to that portal. Portal names are in a different namespace as regular |
54 | cells but portals can also be registered as targeted cells so they can |
55 | have commands sent to them. See more on Portals below. |
56 | |
57 | If the message has a cell name and an optional target name, the cell is |
58 | looked up in the local registry. Cells with just a cell name don't share |
59 | the namespace with cells that have cell and target names. If the cell is |
60 | found the message is delivered by a method. (See how that is chosen |
61 | below.) |
62 | |
63 | If the cell is not found locally it is sent out via a portal with the |
64 | alias DEFAULT. This portal should be connected to a hub which would know |
65 | how to direct the message to the proper destination cell. Typically a |
66 | Stem hub that is a TCP client to a more central server hub will just |
67 | have its portal to the server aliased to DEFAULT. |
68 | |
69 | If the message has the local hub name and couldn't be delivered, it is |
70 | logged and thrown away. Optionally a delivery failure message could be |
71 | sent back to the originator. But this is not the Internet and bounces |
72 | can be automatically fixed in Stem. |
73 | |
74 | NOTE: This brings up the whole subject of message routing. I have been |
75 | thinking about this issue for a while and it is not as tricky as the |
76 | Internet because of several things. First, we can cheat. Stem is |
77 | completely in charge of its routing so it can be smart about itself and |
78 | not deal with worst case situations like the net. A hub can be |
79 | configured to distribute routing information that supports the network |
80 | topology. The discovery of the network and its topology can also be |
81 | automated by a booting Stem network, even from a virgin boot. Remote |
82 | Stem hubs could be installed with minimal (and not customized) |
83 | configurations which will cause itself to connect to a server hub and |
84 | download the real configuration. This simplifies deployment of Stem to a |
85 | new set of boxes. Much more on this subject will be in another design |
86 | notes file. |
87 | |
88 | |
89 | Choosing the Cell Method |
90 | |
91 | Once the destination cell of a message is determined, you then have to |
92 | find out its best method to call to deliver that message. Stem's |
93 | messages can be delivered via a generic method (e.g. 'msg_in') which is |
94 | expected to take any type of message, or via specific methods |
95 | (e.g. 'data_in') which handle selected messages. Here are the rules for |
96 | determining the cell method to call. |
97 | |
98 | If the message type is 'cmd' with a command 'foo' and there is a cell |
99 | method 'foo_cmd', the message is delivered via that method. If a command |
100 | message is delivered via a command method and a value is returned, that |
101 | value is sent back to the 'from' address in a response message. |
102 | |
103 | For all other message types, if the Cell has a method that is the type |
104 | name with '_in' appended to it, that method is used for delivery, |
105 | e.g.; if the message type is 'data', and if the cell has a method named |
106 | 'data_in', that is called with the message as its sole argument. |
107 | |
108 | If the message is not delivered by any of those special methods, it will |
109 | be delivered to the generic method 'msg_in'. This method should exist in |
110 | every cell (except those that have the special methods cover all their |
111 | message types). The method delivery lookup simplifies writing Cells by |
112 | moving the internal dispatching code from the Cell to the registry. |
113 | |
114 | |
115 | |
116 | Stem::Id is a simple module designed to manage a set of unique IDs for |
117 | its owner object, i.e.; it is used by the Stem::SockMsg modules |
118 | to register all of its accepted/connected sockets with unique targets. |
119 | |
120 | Stem::Portal is the class that send messages between hubs over |
121 | pipes. These pipes can be direct sockets or indirect through a secure |
122 | transport such as ssh or stunnel. It receives messages vis the 'send' |
123 | method which are then converted to a string form and written out the |
124 | pipe. The stringify format is currently Data::Dumper but it can be set |
125 | via the configuration of the portal to use Storable, XML or something |
126 | else. Each stringified message is prefixed with 1 or 2 lines containing |
127 | its size and format. Incoming message strings are converted back into |
128 | internal messages and then delivered locally by calling dispatch on |
129 | them. Portals can use any communications channel as long as it gets read |
130 | and write handles. This means that new security and transport protocols |
131 | can be integrated easily into the portal. |