Author: Giovanni Caire (Telecom Italia S.p.A.)
Last Modified: March 26, 2013
Java Platform: Java Standard Edition 6 or later.
JADE version: 4.3 or later.
This tutorial is designed to help readers understanding what Virtual Replicated Agents are, where/when they can be useful and how to implement them. The reader is assumed to be already familiar with JADE main architectural concepts (platform, containers, main-container, agents ...) and JADE programming. If this is not the case we strongly suggest reading the JADE Administration Tutorial and the JADE Programming Tutorial first.
In order to exemplify how to use Virtual Replicated Agents this tutorial makes use of a simple example whose source code is included
in the JADE examples distribution in package examples.replication
.
jade.core.replication.AgentReplicationService
) and the
Agent Mobility Service in all containers of the platform. The first one actually provides replication features, while the second one is used to
clone the master replica when a new replica must be created.
examples.replication
package of the Jade examples distribution, will be presented in next section.
GetValue
action of the ValueManagementOntology
.
This is the agent that actually shows the usage of Virtual Replicated agents: it defines itself as the master replica of a
Virtual Replicated agent and includes a button to create new replicas. Only the master replica keeps its GUI visible.... |--jade/ |--... |--lib/ |--jade.jar |--jadeExamples.jar |--... | |--src/ |--... |--examples/ |--... |--replication/ |-- sources of the Value Provider Agent example
jade
directory and launch the Main Container with the
ValueProviderAgent and ValueReaderAgent on top by typingjava -cp lib/jade.jar;lib/jadeExamples.jar jade.Boot -gui -services jade.core.event.NotificationService;jade.core.mobility.AgentMobilityService;jade.core.replication.AgentReplicationService -agents provider:examples.replication.ValueProviderAgent;reader:examples.replication.ValueReaderAgent
jade
directory and launch a peripheral container by typingjava -cp lib/jade.jar;lib/jadeExamples.jar jade.Boot -container -services jade.core.event.NotificationService;jade.core.mobility.AgentMobilityService;jade.core.replication.AgentReplicationService
setup()
and takeDown()
methods.1 public class ValueProviderAgent extends Agent implements AgentReplicationHelper.Listener { 2 3 private transient ValueProviderAgentGui myGui; 4 private int myValue = 0; 5 6 @Override 7 protected void setup() { 8 try { 9 // Makes this agent become the master replica of a newly defined replicated agent 10 AgentReplicationHelper helper = (AgentReplicationHelper) getHelper(AgentReplicationHelper.SERVICE_NAME); 11 AID virtualAid = helper.makeVirtual(getLocalName()+"_V", AgentReplicationHelper.HOT_REPLICATION); 12 13 // Register to the DF. 14 // NOTE: we use the virtual agent AID (not the concrete agent AID). 15 // In this way requests from remote agents will be automatically spread across 16 // all replicas to achieve load balancing and fault tolerance. 17 DFAgentDescription dfad = new DFAgentDescription(); 18 dfad.setName(virtualAid); 19 ServiceDescription sd = new ServiceDescription(); 20 sd.setType("ValueProvider"); 21 sd.setName("VirtualValueProvider"); 22 dfad.addServices(sd); 23 DFService.register(this, dfad); 24 25 // Register required ontologies and language codecs 26 getContentManager().registerLanguage(new SLCodec()); 27 getContentManager().registerOntology(ValueManagementOntology.getInstance()); 28 29 // Add the behaviour serving requests to read our current value 30 addBehaviour(new OntologyServer(this, ValueManagementOntology.getInstance(), ACLMessage.REQUEST, this)); 31 32 // Show the GUI that allows the user to set the value and to create other replicas 33 myGui = new ValueProviderAgentGui(this, myValue); 34 myGui.setVisible(true); 35 } 36 catch (ServiceException se) { 37 System.out.println("Agent "+getLocalName()+" - Error retrieving AgentReplicationHelper!!! Check that the AgentReplicationService is correctly installed in this container"); 38 se.printStackTrace(); 39 doDelete(); 40 } 41 catch (FIPAException fe) { 42 System.out.println("Agent "+getLocalName()+" - Error registering with the DF"); 43 fe.printStackTrace(); 44 doDelete(); 45 } 46 } 47 48 @Override 49 protected void takeDown() { 50 // Close the GUI (if present) when the agent terminates 51 if (myGui != null) { 52 myGui.dispose(); 53 } 54 }Let's focus first on lines 10 and 11. The first instruction retrieves the ServiceHelper of the AgentReplicationService. The second one allows declaring that this agent is the master replica of a Virtual Replicated Agent. The
HOT_REPLICATION
parameter
specifies that messages directed to the VR agent will be dispatched indifferently to all available replicas. If COLD_REPLICATION
was used, all messages would have been dispatched to the master replica only (other replicas used for fault tolerance purpose only).makeVirtual()
method returns the AID of the VR agent. This is the AID to publish e.g. in DF registrations (see lines from
13 to 23) to exploit the Virtual Replicated Agent mechanism.OntologyServer
behaviour: see the related Javadoc for details)
and show the GUI.takeDown()
method where the GUI (if any) is closed.1 void createReplica(String replicaName, String where) { 2 if (replicaName == null || replicaName.trim().length() == 0) { 3 System.out.println("Replica name not specified"); 4 return; 5 } 6 if (where == null || where.trim().length() == 0) { 7 System.out.println("Replica location not specified"); 8 return; 9 } 10 try { 11 AgentReplicationHelper helper = (AgentReplicationHelper) getHelper(AgentReplicationHelper.SERVICE_NAME); 12 helper.createReplica(replicaName.trim(), new ContainerID(where.trim(), null)); 13 } 14 catch (Exception e) { 15 System.out.println("Agent "+getLocalName()+" - Error creating replica on container "+where); 16 e.printStackTrace(); 17 } 18 }Lines from 2 to 9 just perform checks on the name and location inserted by the user. The
createReplica()
method of the
AgentReplicationHelper
does the real job. As mentioned the actual replica creation is done by cloning the master replica.
As a consequence
afterClone()
method must be redefined to re-initialize transient fields such as registered content languages and ontologiesafterClone()
method.
1 @Override 2 public void afterClone() { 3 // New replicas are created cloning the master replica. 4 // Just after cloning restore transient field such as registered ontologies and language codecs 5 System.out.println("Agent "+getLocalName()+" - Alive"); 6 getContentManager().registerLanguage(new SLCodec()); 7 getContentManager().registerOntology(ValueManagementOntology.getInstance()); 8 }
myValue
field of the ValueProviderAgent class, fully represents the internal state of the
agent.
1 public void setValue(int newValue) { 2 // The call to setValue() will be invoked on other replicas too 3 AgentReplicationHandle.replicate(this, "setValue", new Object[]{newValue}); 4 5 myValue = newValue; 6 System.out.println("Agent "+getLocalName()+": VALUE = "+myValue); 7 }Line 3 in particular ensures that the
setValue()
method is called on all other replicas. Therefore the synchronization
of all replicas of a Virtual Replicated Agent is achieved by replicating calls to methods that are expected to modify the internal state
of the agent. It is responsibility of the programmer to define which call to replicate and how.replicate()
method is not called on the AgentReplicationHelper, as happened for other features
of the Virtual Replicated Agent mechanism, but is provided as a static method of a utility class AgentReplicationHandle
. This
is done to allow calling that method transparently even when the AgentReplicationService is not installed (of course in that case the
method has no effect). In this way it is possible to design an agent to exploit the Virtual Replicated Agent mechanism, but to turn
replication on only when actually needed.
ValueProviderAgent
class implements the AgentReplicationHelper.Listener
interface. This tells the underlying AgentReplication Service that
the master replica will have to be notified whenever a replica related event happens. This is done invoking the methods of the
AgentReplicationHelper.Listener
interface.
replicaAdded()
- Notifies the master replica that a new replica has been successfully created. Note that the replica creation
process occurrs asynchronously.replicaCreationFailed()
- Notifies the master replica that the creation of a new replica has failed.replicaRemoved()
- Notifies the master replica that an existing replica has daid.becomeMaster()
- Notifies the newly selected master replica that the previous master replica has daid.becomeMaster()
method where the newly selected master replica shows
its GUI.
1 @Override 2 public void becomeMaster() { 3 // The old master replica is dead. I'm the new master replica --> Show the GUI 4 System.out.println("Agent "+getLocalName()+" - I'm the new master replica"); 5 myGui = new ValueProviderAgentGui(this, myValue); 6 myGui.setVisible(true); 7 }