import and.Mapping.Graph;
import and.Mapping.Grid;
import and.Mapping.LSM;
-import and.Mapping.Mapping;
import and.Mapping.QM;
import and.Mapping.Simple;
import and.Mapping.Utils;
private ArrayList<GNode> gnodes = null;
private Algo al = null ;
private int count = 0 ;
+ private boolean inDemand = false, operating = false, authorized = false ;
// private boolean daemonListChange ;
// Constructors
SuperNodeListe.Instance().viewAll();
}
- public void sendSurplus(Vector<?> nodes) throws RemoteException {
+ public void sendSurplus(Vector<?> nodes, ArrayList<GNode> _gnodes) throws RemoteException {
System.out.println("Recieved " + nodes.size() + " nodes");
for (int i = 0; i < nodes.size(); i++) {
.setNbOfNodes(Register.Instance().getSize());
new ForwardCount().start();
} catch (Exception e) {
- System.out.println("Error changing Server in SendSurplus : "
+ System.err.println("Error changing Server in SendSurplus : "
+ e);
}
}
+
+ /** Updating gnodes **/
+ if( _gnodes != null )
+ {
+ gnodes = _gnodes ;
+ }
}
public void setToken() throws RemoteException {
System.out.println("Put token to true");
} catch (Exception e) {
- System.out
+ System.err
.println("Unable to heartBeat the next SuperNode with the new Token : "
+ e);
}
public synchronized void workerRegistering(JaceInterface workerStub,
String workerIP, String workerName, int port, GNode g)
throws RemoteException {
- System.out.println("CONNEXION of " + workerName);
+ System.out.println("CONNECTION of " + workerName);
// Create the node
Node noeud = new Node(workerStub);
noeud.setId( count ) ;
noeud.setId( Long.parseLong( workerIP.replace( ".", "" ) ) ) ;
- g.setNode(noeud);
+ g.setNode( noeud ) ;
g.setId( noeud.getId() ) ;
- gnodes.add(g);
+ g.setMapped( false ) ;
+
+ workingOnGnodes() ;
+
+ gnodes.add( g ) ;
// daemonListChange = true ;
.setNbOfNodes(Register.Instance().getSize());
SuperNodeListe.Instance().forwardCountNode();
+ authorized = true ;
SuperNodeListe.Instance().addGNode( g ) ;
+ authorized = false ;
+
+ operating = false ;
}
/****************************************************/
/** Mapping !! Sébastien Miquée **/
/*********************************/
+ /**
+ * Search and return to the requester spawner a register containing
+ * computation nodes plus some extra nodes if needed. This method requires
+ * as parameters the mapping algorithm choice and its parameters, and the
+ * amount of requested nodes and the task to be used, in order to
+ * construct the tasks graph.
+ * @param spawnerIP IP of the requester
+ * @param nbTasks Amount of tasks
+ * @param t Tasks to be executed
+ * @param nbNoeuds Total amount of requested nodes
+ * @param algo Identifier of the mapping algorithm
+ * @param paramAlgo Parameter of the mapping algorithm
+ *
+ * @author Sébastien Miquée
+ */
+ @Override
public Register getRegisterSpawner(String spawnerIP, int nbTasks, Task t,
int nbNoeuds, int algo, double paramAlgo) throws RemoteException {
/** Creation of an empty new Register **/
Register reg = new Register() ;
+ workingOnGnodes() ;
+
/** Initialization of Grid architecture (G5K for now) **/
Grid grid = Utils.createGridG5k(gnodes);
- grid.initClusters();
+// grid.initClusters();
+
/** Creation of tasks GTask **/
ArrayList<GTask> ts = new ArrayList<GTask>();
}
}
}
+
Graph graph = new Graph();
/** Launching the Mapping **/
al.map();
- /** Transforming mapping in register **/
- Mapping mp = al.getMapping();
/** Creating the register **/
- ArrayList<GNode> ag = mp.getMappedGNodes();
+ ArrayList<GNode> ag = al.getMapping().getMappedGNodes();
- for (int i = 0; i < ag.size(); i++) {
+ authorized = true ;
+
+ for( int i = 0; i < ag.size(); i++ ) {
reg.addNode((Node) ag.get(i).getNode());
- gnodes.remove(ag.get(i));
- Register.Instance().removeNode((Node) ag.get(i).getNode());
+ delGNodeFromList( (Node) ag.get(i).getNode(), 2 ) ;
+// gnodes.remove(ag.get(i));
+// Register.Instance().removeNode((Node) ag.get(i).getNode());
}
+
+
+ /** Searching extra nodes if any **/
+ if( nbNoeuds > nbTasks )
+ {
+ int nb = nbNoeuds - nbTasks ;
+ GNode sup = null ;
+
+ for( int i = 0 ; i < nb ; i ++ )
+ {
+ sup = al.getOtherGNode( gnodes ) ;
+ reg.addNodeBeg( (Node) sup.getNode() ) ;
+ delGNodeFromList( (Node) sup.getNode(), 2 ) ;
+ }
+ }
+
+ authorized = false ;
if (ag.size() != 0) {
SuperNodeListe.Instance().forwardCountNode();
}
}
-// else {
-// al = new DefaultMapping( graph, grid, gnodes ) ;
-// /** Launching the Mapping **/
-// al.map();
-//
-// /** Transforming mapping in register **/
-// Mapping mp = al.getMapping();
-//
-// /** Creating the register **/
-// ArrayList<GNode> ag = mp.getMappedGNodes();
-//
-// for (int i = 0; i < ag.size(); i++) {
-// reg.addNode((Node) ag.get(i).getNode());
-// gnodes.remove(ag.get(i));
-// Register.Instance().removeNode((Node) ag.get(i).getNode());
-// }
-//
-// if (ag.size() != 0) {
-// SuperNodeListe.Instance().forwardCountNode();
-// }
-// return getRegisterSpawner(spawnerIP, nbTasks);
-// }
-// daemonListChange = false ;
-
- System.out.println( "Spawner returned reg: " + reg ) ;
+// System.out.println( "Spawner returned reg: " + reg ) ;
- /* Mapping distribution over other Super Nodes */
+ /** Mapping distribution over other SuperNodes */
SuperNodeListe.Instance().setMapping( al ) ;
- /* Returning result */
+ operating = false ;
+
+ /** Returning result **/
return reg ;
}
- /*****************************************/
- /**** Sébastien Miquée ****/
- /** **/
- /** Recherche nouveau noeud **/
- /*****************************************/
- protected GNode delGNodeFromList( Node _n )
+ /**
+ * Suppress a node from the gnodes list if this node is free, or remove
+ * it from the Mapping class of the mapping algorithm if this node is
+ * a computation node. After having done the local suppression of the node
+ * it propagates the suppression to other SuperNodes.
+ * @param _n The fallen node
+ * @param _mode Choice of the list (0: gnodes, 1: mapping, 2:just mapped)
+ *
+ * @author Sébastien Miquée
+ */
+ @Override
+ public GNode delGNodeFromList( Node _n, int _mode ) throws RemoteException
{
- GNode deadGNode = null ;
+ GNode removedGNode = null ;
- for( int i = 0 ; i < gnodes.size() ; i++ )
- {
- if( ((Node)gnodes.get(i).getNode()).getId() == _n.getId() )
+ if( _n != null )
+ {
+ boolean free = false ;
+
+ if( ! operating )
+ {
+ workingOnGnodes() ;
+ free = true ;
+ }
+
+ /** The dead node is not in the mapping **/
+ if( _mode == 0 || _mode == 2)
{
- deadGNode = gnodes.remove( i ) ;
- break ;
+ for( int i = 0 ; i < gnodes.size() ; i++ )
+ {
+ if( ((Node)gnodes.get(i).getNode()).getId() == _n.getId() )
+ {
+ removedGNode = gnodes.remove( i ) ;
+ Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
+ break ;
+ }
+ }
}
+
+ /** The dead node is in the mapping **/
+ if( _mode == 1 )
+ {
+ ArrayList<GNode> temp = al.getMapping().getMappedGNodes() ;
+
+ for( int i = 0 ; i < temp.size() ; i++ )
+ {
+ if( ((Node)temp.get(i).getNode()).getId() == _n.getId() )
+ {
+ removedGNode = temp.get( i ) ;
+ Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
+ break ;
+ }
+ }
+ }
+
+ /** Removing the dead node from the Grid **/
+ if( _mode == 0 || _mode == 1 ) {
+ al.getGrid().removeGNode( removedGNode ) ;
+ }
+
+ /** Propagation of the deletion **/
+ SuperNodeListe.Instance().removeGNode( removedGNode, _mode ) ;
+
+ if( free )
+ {
+ operating = false ;
+ }
+
}
-// daemonListChange = true ;
+ return removedGNode ;
+ }
+
+
+ /**
+ * Determine if this SuperNode can operate on the gnodes list.
+ * It asks other SuperNodes to know if their are working on this list
+ * and set the authorization, or not.
+ *
+ * @author Sébastien Miquée
+ */
+ private void workingOnGnodes()
+ {
+ boolean tmp = true ;
- SuperNodeListe.Instance().removeGNode( deadGNode ) ;
+ inDemand = false ;
+ operating = false ;
+
+ while( ! operating )
+ {
+ inDemand = true ;
+ tmp = true ;
+
+ tmp = tmp && SuperNodeListe.Instance().workingOnGnodes() ;
+
+ operating = tmp ;
+
+ if( ! tmp )
+ {
+ inDemand = false ;
+
+ try {
+ Thread.sleep( 10 ) ;
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
- return deadGNode ;
+ inDemand = false ;
}
-
+ /**
+ * Search and return a new node when one failed or when JaceP2P needs another
+ * one. For the first case, the given failed node should not be null, and
+ * null in the other case.
+ * @param _spawnerIP IP of the requester
+ * @param _deadNode The failed node
+ *
+ * @author Sébastien Miquée
+ */
+ @Override
public Node getNewNode( String _spawnerIP, Node _deadNode ) throws RemoteException
{
Node node = null ;
GNode remp = null, gnode = null ;
+ /** Can we use gnodes ?**/
+ workingOnGnodes() ;
if( _deadNode != null )
{
- gnode = delGNodeFromList( _deadNode ) ;
-
- /* TODO */
- Mapping mp = al.getMapping() ;
-
-// ArrayList <GNode> mapped = mp.getMappedGNodes() ;
-
- mp.removeGNode( gnode ) ;
-
- /*****************/
- // mettre directement dans Algo !
-// for( int i = 0 ; i < mapped.size() ; i++ )
-// {
-// gnode = mapped.get( i ) ;
-// tmp = (Node) gnode.getNode() ;
-// if( tmp.getId() == _deadNode.getId() )
-// {
-// mapped.remove( i ) ;
-// break ;
-// }
-// }
-
+ authorized = true ;
+
+ gnode = delGNodeFromList( _deadNode, 1 ) ;
+
remp = al.replaceNode( gnode, gnodes ) ;
if( remp != null )
{
System.out.println( "Replacing node found." ) ;
- node = (Node) remp.getNode() ;
- delGNodeFromList( node ) ;
-// gnodes.remove( remp ) ;
-// Register.Instance().removeNode( node );
+
+ remp.setMapped( true ) ;
+
+ delGNodeFromList( (Node) remp.getNode(), 2 ) ;
+
+ authorized = false ;
+
SuperNodeListe.Instance().forwardCountNode();
} else {
System.err.println( "Replacing node not found !!" ) ;
}
} else {
- remp = al.getOtherGNode() ;
+ remp = al.getOtherGNode( gnodes ) ;
if( remp != null )
{
System.out.println( "Other new node found." ) ;
- node = (Node) remp.getNode() ;
- delGNodeFromList( node ) ;
-// gnodes.remove( remp ) ;
-// Register.Instance().removeNode( node );
+
+ remp.setMapped( true ) ;
+
+ authorized = true ;
+
+ delGNodeFromList( (Node) remp.getNode(), 2 ) ;
+
+ authorized = false ;
+
SuperNodeListe.Instance().forwardCountNode();
} else {
System.err.println( "Other new node not found !!" ) ;
}
}
+
+ /** Updating all mapping **/
+ updateMappedNode( gnode, remp ) ;
+ propagateReplaceNode( gnode, remp ) ;
+
+
+ /** Free the gnodes use **/
+ operating = false ;
+
return node ;
}
+ /**
+ * Replace a failed GNode in the mapping by another one.
+ * This method is called by the SuperNodeList, to broadcast the modification.
+ * @param _dead The failed node
+ * @param _remp The replacing node
+ *
+ * @author Sébastien Miquée
+ */
+ @Override
+ public void updateMappedNode( GNode _dead, GNode _remp )
+ {
+ if( _remp != null )
+ {
+ int pos = 0 ;
+
+ pos = al.getMapping().getIdOfAssociation( _dead ) ;
+
+ if( pos != -1 )
+ {
+ /** Changing the node in the mapping **/
+ al.getMapping().getMapping().get( pos ).setGNode( _remp ) ;
+
+ System.out.println( "Succesfully replacing the fallen node in the mapping." ) ;
+ }
+
+ /** Changing the status in the grid **/
+ al.getGrid().setMappedStatus( _remp, true ) ;
+
+ al.updateGrid() ;
+ } else {
+ System.err.println( "The new GNode is null!" ) ;
+ }
+ }
+
+
+ /**
+ * Inform all SuperNodes of the replacement of a failed computing node.
+ * @param _dead The failed node
+ * @param _remp The replacing node
+ *
+ * @author Sébastien Miquée
+ */
+ private void propagateReplaceNode( GNode _dead, GNode _remp ) throws RemoteException
+ {
+ if( _remp != null )
+ {
+ SuperNodeListe.Instance().propagateReplaceNode( _dead, _remp ) ;
+ }
+ }
+
/**********************************************************/
/**********************************************************/
+
+ @Override
+ /**
+ * Add a new node in the list.
+ * @param _g The new node
+ *
+ * @author Sébastien Miquée
+ */
+ public void addGNode( GNode _g ) throws RemoteException
+ {
+ if( _g != null )
+ {
+ boolean free = false ;
+
+ if( ! operating )
+ {
+ workingOnGnodes() ;
+ free = true ;
+ }
+
+ gnodes.add( _g ) ;
+
+ if( free )
+ operating = false ;
+ }
+ }
-// public Node getNewNode(String spawnerIP) throws RemoteException {
-// boolean found = false;
-// int i = 0;
-// Node tmpNode = null;
-// SuperNodeData d = null;
-// //int passage = 0;
-// String snode_IP;
-// JaceSuperNodeInterface stub = null;
-//
-// try {
-// System.out.println("\n" + spawnerIP
-// + " (spawner) requests a new node : ");
-// while (i < Register.Instance().getSize() && found == false) {
-// tmpNode = Register.Instance().getNodeAt(i);
-//
-// if (tmpNode.getAppliName() == null
-// && tmpNode.getAliveFlag() == true) {
-// tmpNode.setAppliName("notnull");
-// found = true;
-//
-// // enlever maintenant le noeud du register de
-// // SuperNode??????
-// // System.out.println("je remove le noeud car il va beater le spawner (getNewNode)");
-// // Register.Instance().removeNodeAt(i);
-// Register.Instance().removeNode(tmpNode);
-// // Register.Instance().removeNode(tmpNode.getIP());
-//
-// int index = SuperNodeListe.Instance().existSuperNode(
-// LocalHost.Instance().getIP());
-//
-// ((SuperNodeData) SuperNodeListe.Instance().getListe()
-// .elementAt(index)).setNbOfNodes(Register.Instance()
-// .getSize());
-// SuperNodeListe.Instance().forwardCountNode();
-// }
-// i++;
-// }
-// } catch (Exception e1) {
-// System.out.println("... plante en cherchant chez moi");
-// }
-//
-// // Register.Instance().viewAll();
-// SuperNodeListe.Instance().viewAll();
-//
-// try {
-// // si pas assez de noeud sur ce superNode,
-// if (found == false) {
-// System.out.println("pas de noeud dispo chez moi");
-//
-// SuperNodeListe snodeListTmp = SuperNodeListe.Instance().clone();
-// // while ( (found == false) && (passage <
-// // SuperNodeListe.Instance().getSize()) ) {
-// while ((found == false) && (snodeListTmp.getSize() > 0)) {
-// // System.out.println("passage = " + passage);
-// // d = SuperNodeListe.Instance().getBestSuperNodeData();
-// d = snodeListTmp.getBestSuperNodeData();
-// System.out.println("KKKKKKKKKKKKKKK ......... le best c "
-// + d.getIP() + " il en a " + d.getNbOfNodes());
-// if (d != null) {
-// snode_IP = d.getIP();
-// // si c moi, je passe au suivant
-// if (LocalHost.Instance().getIP().equals(snode_IP)) {
-// // passage++;
-// System.out
-// .println("OUUUUPS, c moi dc je tente un autre");
-// snodeListTmp.removeSuperNode(d);
-// continue;
-// }
-//
-// stub = d.getStub();
-//
-// if (stub != null) {
-// try {
-// Register tmpReg = stub.reserveLocalNodes(1);
-// if (tmpReg != null) {
-// // for (int j = 0; j < tmpReg.getSize();
-// // j++) {
-// System.out.println("IL EN A 1 !!!!!!!");
-// tmpNode = tmpReg.getNodeAt(0);
-// found = true;
-// System.out.println("le snode " + snode_IP
-// + " me reserve le noeud demande");
-// } else {
-// System.out
-// .println("MERDE !!! pas de noeud dispo sur "
-// + snode_IP);
-// System.out
-// .println("Je demande un noeud a un autre");
-// }
-//
-// } catch (Exception e) {
-// System.out
-// .println("le snode est mort, je demande les noeuds a un autre");
-// // remettre localement a 0 le nb de noeuds de ce
-// // superNode
-// SuperNodeListe.Instance().modifCountNode(
-// snode_IP, 0);
-// snodeListTmp = SuperNodeListe.Instance()
-// .clone();
-// }
-// }
-// } else {
-// System.out
-// .println("PUTAIN !!!! aucun noeud encore dispo sur les snode");
-// // passage = SuperNodeListe.Instance().getSize();
-// }
-// // passage++;
-// snodeListTmp.removeSuperNode(d);
-// }
-// }
-// } catch (Exception e2) {
-// System.out.println("plante en cherchant chez les autres");
-// }
-//
-// // si pas assez de noeud sur tous les superNode,
-// if (found == false) {
-// System.out.println("aucun noeud dispo dans le systeme");
-// } else {
-// System.out.println("je lui donne son noeud");
-// }
-//
-// return tmpNode;
-// }
-// public Register reserveLocalNodes(int nb) throws RemoteException {
-// Register reg = null;
-// System.out
-// .println("\nA superNode or a Spawner asks me for a register of "
-// + nb + " Daemons");
-//
-// int count = 0;
-// int i = 0;
-// Node tmpNode;
-//
-// if (Register.Instance().getSize() == 0) {
-// return new Register();
-// } else {
-// reg = new Register();
-//
-// while (i < Register.Instance().getSize() && count < nb) {
-// tmpNode = Register.Instance().getNodeAt(i);
-//
-// if (tmpNode.getAppliName() == null
-// && tmpNode.getAliveFlag() == true
-// /* && tmpNode.getNbOfBeats() > 10 */) {
-// // if node available, alive and not recently connected, then
-// tmpNode.setAppliName("notnull");
-// reg.addNode(tmpNode);
-//
-// // remove now the node from SuperNode or later ?
-// // System.out.println("I remove the Node from SuperNode beating it will now beat the Spawner");
-// Register.Instance().removeNode(tmpNode);
-// count++;
-// }
-// // increment counter only y Node NOT REMOVED
-// else {
-// i++;
-// }
+// @Override
+// public void removeGNode( GNode _g ) throws RemoteException
+// {
+// if( _g != null )
+// {
+// boolean free = false ;
+//
+// if( ! operating )
+// {
+// workingOnGnodes() ;
+// free = true ;
// }
-//
-// // Register.Instance().viewAll();
-// System.out.println("Number of Daemons reserved on me : " + count);
-// // Inform other SuperNodes that some Daemons initialy registered on
-// // me
-// // are no longer available because reserved for the spawner that
-// // invoked me
-// int index = SuperNodeListe.Instance().existSuperNode(
-// LocalHost.Instance().getIP());
-// ((SuperNodeData) SuperNodeListe.Instance().getListe().elementAt(
-// index)).setNbOfNodes(Register.Instance().getSize());
-//
-// if (count != 0) {
-// SuperNodeListe.Instance().forwardCountNode();
+//
+// for( int i = 0 ; i < gnodes.size() ; i++ )
+// {
+// if( ((Node)gnodes.get(i).getNode()).getId() == ((Node)_g.getNode()).getId() )
+// {
+// gnodes.remove( i ) ;
+// Register.Instance().removeNodeOfName( _g.getName() ) ;
+// break ;
+// }
// }
-//
-// System.out.println("I return " + count + " nodes");
-// // System.out.println( reg ) ;
-// // SuperNodeListe.Instance().viewAll() ;
-// return reg;
+//
+// if( free )
+// operating = false ;
// }
+//
// }
+
+ /**
+ * Set the local mapping with another done on an other SuperNode.
+ * @param _al The new mapping
+ *
+ * @author Sébastien Miquée
+ */
@Override
- public void addGNode( GNode _g ) throws RemoteException
+ public void setMapping( Algo _al ) throws RemoteException
{
- if( _g != null )
- gnodes.add( _g ) ;
+ al = _al ;
}
-
+
@Override
- public void removeGNode( GNode _g ) throws RemoteException
+ /**
+ * Allow or deny the use of operations on the gnodes list, in order to
+ * do a mapping operation.
+ * @return The authorization or not to block gnodes
+ *
+ * @author Sébastien Miquée
+ */
+ public boolean blockForMapping() throws RemoteException
{
- if( _g != null )
+ while( inDemand )
{
- for( int i = 0 ; i < gnodes.size() ; i++ )
- {
- if( ((Node)gnodes.get(i).getNode()).getId() == ((Node)_g.getNode()).getId() )
- {
- gnodes.remove( i ) ;
- break ;
- }
+ try {
+ Thread.sleep( 10 ) ;
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
}
+ if( operating && ! authorized )
+ {
+ return false ;
+ } else {
+ return true ;
+ }
}
-
+ /**
+ * Return the array containing the current not mapped nodes available.
+ * @return The array of available nodes
+ *
+ * @author Sébastien Miquée
+ */
@Override
- public void setMapping( Algo _al ) throws RemoteException
+ public ArrayList<GNode> getGNodes() throws RemoteException
{
- al = _al ;
+ return gnodes ;
}
}