In the original version of SEER, agents ran as pieces of python code with callbacks all within the same thread. In MAGI, each agent runs in its own thread or process that is started by a node daemon. When adding an agent, you are free to chose your method.
The source object provided is interpreted as python code and the daemon will search for the function getAgent in the provided code. If not found, execution fails. If found, a new thread is created and the object returned from getAgent is used. At load time, the run method on the returned object is called as run(messenger, args) and is expected not to return until the agent is done or is asked to stop. The arguments are:
- A magi.daemon.daemon.MessagingWrapper object for sending and receiving messages as well as the dock assigned to the agent
- The args list from the exec call as an array
When the agent is to be unloaded, the object method stop is called with no arguments. It is expected that the run method should eventually finish after the stop method has been called.
The messagaing wrapper interface:
def joinGroup(self, group): pass
def leaveGroup(self, group): pass
def listenDock(self, dock): pass
def unlistenDOck(self, dock): pass
def send(self, msg, args=None): pass
def next(self, block=True, timeout=None): pass
Example Strawman agent:
class MyAgent(object):
def run(self, messenger, args):
""" This is called when its time to start in the agents own thread """
pass
def stop(self):
""" This is called when its time to stop, probably use a flag variable to indicate time to stop """
pass
def getAgent():
return MyAgent()
Process Value argv[0] name argv[1] assigned dock argv[2..] args passed in message to exec agent
Processes are started with the arguments specified in the Exec message. There will be a localhost only server running on port 18809. This server stream acts the same as the stdin/stdout of the pipe interface. The socket interface is also the method for scripts to connect to the daemon process.
Process Value argv[0] name argv[1] assigned dock argv[2..] args passed in message to exec agent stdin pipe with incoming serialized messages stdout pipe for outgoing serialized messages stderr tempfile
Processes are started with stdin as a source of messages, stdout as a path for outgoing messages and stderr will be captured in a tempfile that can be sent or queried. The arguments to the process can be specified in the Exec message. The setup is effectively the same as the socket interface with stdin/stdout replacing a TCP socket.
We make use of the same code that perform messaging passing for stream based messaging in the transmission of data to agents running as processes. For this reason, the encoding of messages across the stream look very similar. Libraries will be provided in Python, Perl and C.
PREAMBLE TotalLen HeaderLen [Header] [Data]
Header Format Content Size Description Length 4 bytes header + data not including 4 length bytes Header Length 2 bytes length of just the header not including this length value Type 1 byte The agent process request Headers variable type-length-value options (byte, byte, variable) Data variable the actual message data
Types Name Code Description Join Group 1 Request for the node to join a group, the value is in the data portion Leave Group 2 Request for the node to leave a group, the value is in the data portion Listen Dock 3 Request that messages for dock are delivered to this agent, value in data Unlisten Dock 4 Request to stop delivering dock messages to this agent, value in data Message 5 Send/Receive a message, encoded MAGIMessage in data, header contains delivery requests for sending
Possible Header Options Name Code Description Acknowldgement 1 Request that the message is acknowledgement or restransmission occurs, no value Source Ordering 2 Request that message is delivered in order as sent by this host, no value Timestamp 3 Request that message is delivered on or after the given timestamp, expects 4 byte time value
This is an example of sending a message from the agent to the daemon requesting source ordering and timestamp processing for the message.
Field Data Preamble MAGI[0x88]PKT Length 1234 HeaderLength 9 Type 5 (Send Message) Request 1 2, 0 (Source Ordering) Request 2 3, 4, 1234567 (Timestamp) Data Encoded MAGI Message (See Wire Formats)
Encoding 1 2 3 4 5 6 7 8 9 10 11 12 MAGI[0x88]PKT 1234 9 5 2 0 3 4 1234567 ... 1223 bytes of encoded MAGI Message
This is an example of the agent requesting that the daemon join the messaging group MyGroup.
Field Data Preamble MAGI[0x88]PKT Length 9 HeaderLength 1 Type 1 (Join Group) Data “MyGroup”
Encoding 1 2 3 4 5 6 7 8 9 10 11 12 MAGI[0x88]PKT 9 1 1 “MyGroup” —-