• No results found

Agent Message Routing

In document Contributions to Edge Computing (Page 60-65)

2.4 Cresco Architecture

3.2.3 Agent Message Routing

The ability to pass messages between components is a fundamental aspect of dis- tributed systems, agent-based frameworks, and actor-model concurrency. In the implementation of the Cresco Agent a local concurrently accessible FIFO (first-in- first-out) queue named AgentEngine.msgInQueue is used as a message mailbox. The MsgInQueue process passes messages from the AgentEngine.msgInQueue to the ms- gInProcessQueue executor service. Executors are discussed in Section 3.3.2, Executor Class. The executor service spawns1 a msgRoute thread for each incoming message.

The msgRoute thread determines the delivery or execution path of the incoming message. Once the message has been delivered the execution thread is terminated.

The following variables are used by the msgRoute thread to determine message destination:

• AgentEngine.region: Region name of the routing agent. • AgentEngine.agent: Agent name of the routing agent. • src region: Source region name of incoming message. • src agent: Source agent name of incoming message. • src plugin: Source plugin name of incoming message. • dst region: Destination region name of incoming message. • dst agent: Destination agent name of incoming message. • dst plugin: Destination plugin name of incoming message.

The pseudocode shown in Algorithm 1 generates routeString, a 6 bit2 boolean expression [RXr∧ RXa∧ RXp∧ T Xr∧ T Xa∧ T Xp] representing a contextual message

type. RouteString and the resulting routePath integer representation values are based on source and destination message parameters in respect to agents settings. There are three possible actions for the routing engine to take for each message:

• drop: Discard the message.

• getCommandExec: Execute message on the agent. • sendT oP lugin: Send message to a plugin on the agent.

The route path truth table is shown in Table 3.1, where F0 and F1 represent

getCommandExec and sendT oP lugin respectively. The default route action is to drop messages, which are omitted from the table.

Algorithm 1 Determine RoutePath

Input: src region, src agent, src plugin, dst region, dst agent, dst plugin Output: routePath = [Base 10 value of route code]

if src region = AgentEngine.region then RXr ← 1

else

RXr ← 0

end if

if src agent = AgentEngine.agent then RXr ← 1

else

RXr ← 0

end if

if src plugin 6= null then RXr ← 1

else

RXr ← 0

end if

if dst region = AgentEngine.region then T Xr ← 1

else

T Xr ← 0

end if

if dst agent = AgentEngine.agent then T Xr ← 1

else

T Xr ← 0

end if

if dst plugin 6= null then T Xr ← 1

else

T Xr ← 0

end if

routeString ← RXr+ RXa+ RXp+ T Xr+ T Xa+ T Xp

{routeString: a string concatenation representing a 6 bit binary value.} routeP ath ← Integer.parseInt(routeString, Base2)

Table 3.1: Agent Route Table RoutePath RXr RXa RXp T Xr T Xa T Xp F0 F1 56 1 1 1 0 0 0 1 0 57 1 1 1 0 0 1 1 0 58 1 1 1 0 1 0 0 1 59 1 1 1 0 1 1 0 1 60 1 1 1 1 0 0 1 0 61 1 1 1 1 0 1 1 0 62 1 1 1 1 1 0 0 1 63 1 1 1 1 1 1 0 1

The boolean expressions for our two actionable route cases are shown below: • getCommandExec: RXr∧ RXa∧ RXp∧ T Xr∧ T Xa∧ T Xp

• sendT oP lugin: RXr∧ RXa∧ RXp∧ T Xr∧ T Xa∧ T Xp

It not necessary to calculate boolean expressions for simple routing rules, like those used by the agent. In the case of agent routing, conditional expressions applied to source and destination addresses are sufficient to implement route procedures. How- ever, as we will show in Section 3.6.4, Controller Message Routing, for routing cases with more variables developing complex conditional statements becomes difficult and are error prone. For complex cases routePath values are used with lookup tables to determine route actions.

The MsgRoute workflow is shown in Figure 3.4.

Messages are either routed to a specific plugin or executed on the agent itself. The route thread terminates on route completion, which is sufficient for unidirec- tional messages. However, there are cases where we want a response to our messages. Typically, method execution is a blocking function, where the calling instance must wait (is blocked) for a method to complete before continuing its processing. This mode of operation is considered a synchronous operation. In a distributed system

Incoming MsgEvent isRegional Message Set Loop Count isAgent Message No isController Yes Forward to Controller Plugin Yes Forward to Chanel Plugin No For this Agent Yes Forward to Controller Plugin No Execute on Agent Yes Terminate Route Thread

Figure 3.4: MsgEvent Routing process for the Cresco-Agent

with many agents and plugins we do not want to block the execution path, while waiting on methods to complete. The ability to call methods without waiting for the method to complete is considered an asynchronous (non-blocking) operation. In the context of the Cresco framework we define Remote Procedure Calls (RPC) as bi- directional asynchronous method executions. These calls can be performed between all Cresco components. RPC calls in the Cresco framework is explained in detail in Section 3.5.4, Remote Procedure Call.

As previously mentioned, MsgEvent messages destined for agents are routed to the getCommandExec process. The getCommandExec process implements the Cresco Agent API described in the next subsection.

In document Contributions to Edge Computing (Page 60-65)