Design¶
Approach¶
The preferred approach is to leverage a Message Bus and possibly a Messaging Framework that uses the message bus for transport. The advantages over home grown and/or point-to-point solutions are as follows:
- Hub and Spoke topology. Each node knows the address of the broken but not each other.
- Key-based routing. Nodes are associated with properties instead of IP addresses.
- Reliable message delivery.
- Message queueing.
- Automatic reconnect behaviour.
- And probably others …
Dispatch Architecture:
Messaging¶
A Messaging Framework provides RMI (Remote Method Invocation) & Event semantics on top of messaging. This gives application developers an easy to use abstraction and hides some of the complexities of exchange and dispatching. Especially in OO applications, invoking a method remotely on an agent without regard for message exchange and routing enhances reliability and productivity.
Requirements Summary:
- Key-based routing based on consumer ID.
- Synchronous RMI.
- Asynchronous RMI.
- Fire and Forget
- Callbacks
- Returned values.
- Exception propagation.
- Easy to use.
- Easy to extend classes/method exposed for RMI.
- Events
- Support multiple API versions.
Synchronous RMI:¶
Asynchronous RMI:¶
Messages¶
The message format is json:
- Security-Wrapper:
- signature - A base64 encoded signature.
- message - A json message with stricture of: (Request | Result | Exception)
- Envelope:
- sn - Serial Number (uuid).
- version - The API version.
- routing - A tuple containing the amqp (sender, destination).
- secret - The (optional) shared secret used for request authentication. DEPRECATED in 2.7.
- pam - The (optional) PAM authentication credentials. DEPRECATED in 2.7.
- replyto - The reply amqp address (optional).
- one of
- request - An RMI request. See: Request.
- result - An RMI result. Has value of: (Result | Exception).
- status - An RMI request status report. See: Status.
- timestamp - An ISO-8601 reply timestamp (UTC).
- data - User defined data.
- Request(Envelope):
- classname - The target class name.
- cntr - The (optional) remote class constructor arguments. format: ([],{}).
- method - The target instance method name.
- args[] - The list of parameters passed to method
- kws{} - The named keyword arguments passed to method.
- Status(Envelope):
- status - A request status with value of
- accepted - Accepted by the agent and queued.
- rejected - Rejected by the agent.
- started - The request has started execution.
- progress - Progress is begin reported. See: Progress.
- Progress(Status):
- total - The total number of items to be completed.
- completed - The number of items completed.
- details - Reported details. Can be anything.
- Result(Envelope):
- retval - The returned data. Can be anything.
- Exception(Envelope)
- exval - The formatted exception (including trace).
- xmodule - The exception module name.
- xclass - The exception class.
- xstate - The exception state. Contains the exception __dict__.
- xargs - The exception args attribute when subclass of Exception.
Example RMI request message:
{
"sn": "e7e91fb6-611b-4284-a9ed-ac1636b2c709",
"routing": [
"cfa806a4-919a-495f-b1dd-3fc11be9a8d0" ,
"19802a28-a18c-4ae3-ac57-b7a2e78a427a"
],
"replyto": "cfa806a4-919a-495f-b1dd-3fc11be9a8d0",
"version": "0.2"
"request": {
"classname": "Dog",
"method": "bark"
"args": ["hello"],
"kws": {}
}
}
Example reply:
{
"sn": "e7e91fb6-611b-4284-a9ed-ac1636b2c709",
"version": "0.2",
"result": {
"retval": "Yes master. I will bark because that is what dogs do."
}
}
Example status reply:
{
"origin": "123",
"status": "accepted",
"version": "0.2",
"sn": "985cb165-d291-47de-ab34-ecb20895384e",
"data": "group 2"
}