In this section we have a closer look at how to set up the communication in a simulation model. Agents communicate by messages. Messages are sent via ports. There are inports for incoming messages and outports for outgoing communication. Ports can be connected like extension cords. Please note that connections are always directed from source to destination.
After each simulation step the simulator calls a message forwarding mechanism, so messages are available at their destinations at the start of the next simulation cycle (but not before). There are two distinct concepts on how to organize the communication in an agent model: direct messaging and routing. This section focusses on direct messaging, please refer to the next chapter for an introduction of the routing concept.
Setting up connections
The most obvious apporach is to simply connect agents directly. Considering only two agents, A and B, this could be done like this: First we create in- and outport within the constructor of each agent.
addInport(new SinglePort(this)); // This is already done in the superclass constructor of each entity. addOutport(new SinglePort(this));
Next, we connect the agents by using the port’s connectTo
method. In this way, we establish a directed from-to-relationship.
agentA.getOutport().connectTo(agentB.getInport()); agentB.getOutport().connectTo(agentA.getInport());
As in real life, the content to be sent has to be wrapped in an envelope, done by the Message
class. This classe contains all necessary address information for the coressponding forwarding mechanism. Sending a message from agent A to agent B during a simulation run can be done like this:
public Time doEvent(Time time) { Message msg=new Message(this,"Hello World!"); getOutport().write(msg); return getTimeOfNextEvent(); }
Receiving the message in agent B is also simple:
Collection<Message>=getInport.readAll(); // read all messages, messages are NOT removed Message msg=getInport().poll(); // ONE message is removed
Finally, you have to choose an appropriate MessageForwardingStrategy
when initializing the simulator:
Simulator simulator=new SequentialDESimulator(model,new DirectMessageForwarding());
Communicating across domain borders
In the last section, we looked at exchanging message between agents within the same domain. But what if the destination is part of another domain?
In this case, we have to supply the domain also with in- and outports. Connecting through the domain boundary can then be done like this:
agentA.getOutPort().connectTo(domainA.getOutPort()); domainA.getOutport().connectTo(domainB.getInport()); domainB.getInport().connectTo(agentB.getInport());
Please note the direction of the ports. First we have to lead a message out of the current submodel. Then it is directed into the other domain. The final destination is always the inport of an agent. Since the message has to be forwarded along three connections (instead of one), the forwarding strategy has to be adjusted accordingly.
Simulator simulator=new SequentialDESimulator(model, new RecursiveMessageForwarding());
Forwarding Strategy | Usage |
DirectMessageForwarding | Only one forwarding cycle, use if agents are connected directly. |
RecursiveMessageForwarding | Multiple forwarding cycles, general purpose, should work with most models, supports routing models. |
RoutedMessageForwarding | Specialized strategy, only use for routing models. |
Ports
Currently, there are three types of ports, listed in the table below. SinglePort
should be used as inport and for a single connection between two agents. The MultiPort
broadcasts a message to all its connected agents and is versatile for use in cellular automata. Both ports do not look up the destination address of a message (thus it can be set to null
) since the connection itself yields the information about the destination.
The SwitchPort
can be connected to several agents, but a message is only forwarded to one agent given in the message’s destination. If the destination is not connected to the port, an error will be thrown.
Port | Funtionality |
SinglePort | Use for single connections. Inport are initialized as SinglePort by default. |
MultiPort | Broadcasts messages to all connected agents. |
SwitchPort | Copies message only to the agent given as destination of the message. |
Summary
- Create ports inside the constructor when an agent is initialized.
- Establish connections by a model building routine from outside of an agent and before the simulation run.
- Regard that connections are always directed from source to destination (from-to-relationship).
- Choose the appropriate port type and forwarding strategy that fits your model design.
- Never change connections during a simulation run directly!
- To change a model during a simulation run, use change requests (see dynamic model changes).
Next have a look at the routed messaging concept suitable for larger and more complex models.