3 import java.rmi.RemoteException;
4 import java.rmi.server.UnicastRemoteObject;
5 import java.util.ArrayList;
6 import java.util.Vector;
8 import and.Mapping.Algo;
9 import and.Mapping.DefaultMapping;
10 import and.Mapping.GNode;
11 import and.Mapping.GTask;
12 import and.Mapping.Graph;
13 import and.Mapping.Grid;
14 import and.Mapping.LSM;
15 import and.Mapping.QM;
16 import and.Mapping.Simple;
17 import and.Mapping.Utils;
20 public class JaceSuperNodeServer extends UnicastRemoteObject implements
21 JaceSuperNodeInterface {
22 private static final long serialVersionUID = 1L;
26 private ArrayList<GNode> gnodes = null;
27 private ArrayList<Algo> algos = null ;
28 private int count = 0 ;
29 private boolean inDemand = false, operating = false, authorized = false ;
30 // private boolean daemonListChange ;
34 public JaceSuperNodeServer(int timeBeat) throws RemoteException {
37 gnodes = new ArrayList<GNode>() ;
38 algos = new ArrayList<Algo>() ;
39 // daemonListChange = true ;
42 public int getSuperNodeBeat() throws RemoteException {
46 public Vector<?> sendStub(String IP, int port, JaceSuperNodeInterface stub)
47 throws RemoteException {
48 SuperNodeListe.Instance().addStubOf(IP, port, stub);
49 System.out.println("Added new superNode (" + IP
50 + ") to list and return List");
51 return SuperNodeListe.Instance().getListe();
54 public void updateCountNode(String IP, int nb) throws RemoteException {
55 SuperNodeListe.Instance().modifCountNode(IP, nb);
56 // System.out.println( "SuperNode " + IP + " has registered " + nb +
58 SuperNodeListe.Instance().viewAll();
61 public void sendSurplus(Vector<?> nodes, ArrayList<GNode> _gnodes) throws RemoteException {
62 System.out.println("Recieved " + nodes.size() + " nodes");
64 for (int i = 0; i < nodes.size(); i++) {
65 Register.Instance().getListe().add((Node) nodes.elementAt(i));
67 System.out.println("Adding "
68 + ((Node) nodes.elementAt(i)).getName());
71 ((Node) nodes.elementAt(i)).getStub().updateHeart(
72 LocalHost.Instance().getSuperNodeStub());
73 int index = SuperNodeListe.Instance().existSuperNode(
74 LocalHost.Instance().getIP());
75 ((SuperNodeData) SuperNodeListe.Instance().getListe()
77 .setNbOfNodes(Register.Instance().getSize());
78 new ForwardCount().start();
79 } catch (Exception e) {
80 System.err.println("Error changing Server in SendSurplus : "
85 /** Updating gnodes **/
92 public void setToken() throws RemoteException {
93 System.out.println("I got Token");
95 TokenThread.Instance().setToken();
98 HeartBeatSNode.Instance().getServer().beating(true);
100 System.out.println("Put token to true");
101 } catch (Exception e) {
103 .println("Unable to heartBeat the next SuperNode with the new Token : "
108 public void updateHeart(JaceSuperNodeInterface stub) throws RemoteException {
109 System.out.println("I change to ping a superNode");
111 HeartBeatSNode.Instance().setServer(stub);
114 public synchronized void removeSuperNode(SuperNodeData d)
115 throws RemoteException {
116 SuperNodeListe.Instance().removeSuperNode(d);
119 /****************************************************/
120 /****************************************************/
122 // Register a Daemon in the Register.Instance() of the SuperNode
123 public synchronized void workerRegistering(JaceInterface workerStub,
124 String workerIP, String workerName, int port, GNode g)
125 throws RemoteException {
126 System.out.println("CONNECTION of " + workerName);
129 Node noeud = new Node(workerStub);
130 noeud.setName(workerName);
131 noeud.setIP(workerIP);
132 noeud.setAliveFlag(true);
133 noeud.setAliveTime();
135 noeud.setAppliName(null);
136 noeud.setNbOfBeats(0);
137 noeud.setId( count ) ;
138 noeud.setId( Long.parseLong( workerIP.replace( ".", "" ) ) ) ;
141 g.setId( noeud.getId() ) ;
142 g.setMapped( false ) ;
148 // daemonListChange = true ;
150 // Insert the node in the Register.Instance() of the Super Node
151 Register.Instance().addNode(noeud);
153 // Register.Instance().viewAll() ;
154 // SuperNodeListe.Instance().viewAll() ;
156 // Inform the other superNode and tell them the nb of Daemon I have
158 int index = SuperNodeListe.Instance().existSuperNode(
159 LocalHost.Instance().getIP());
161 ((SuperNodeData) SuperNodeListe.Instance().getListe().get(index))
162 .setNbOfNodes(Register.Instance().getSize());
163 SuperNodeListe.Instance().forwardCountNode();
166 SuperNodeListe.Instance().addGNode( g ) ;
172 /****************************************************/
173 /****************************************************/
175 // HeartBeat that detects if a Daemon is dead or alive
176 public void beating(JaceInterface stub) throws RemoteException {
177 Node noeud = Register.Instance().getNodeOfStub(stub);
180 noeud.setAliveFlag(true);
181 noeud.setAliveTime();
182 noeud.incrementNbOfBeats();
184 // System.out.println( noeud.getName() + " is pinging me" ) ;
186 // System.out.println( noeud.getName() +
187 // ".................. is not in my list" ) ;
191 // HeartBeat that detects if a Super Node is dead or alive
192 public void beating(boolean token) throws RemoteException {
193 ScanThreadSuperNode.Instance().setAliveTime();
194 ScanThreadSuperNode.Instance().setToken(token);
196 // System.out.println( "Super Node is pinging me" ) ;
200 /*********************************/
201 /** Mapping !! Sébastien Miquée **/
202 /*********************************/
205 * Search and return to the requester spawner a register containing
206 * computation nodes plus some extra nodes if needed. This method requires
207 * as parameters the mapping algorithm choice and its parameters, and the
208 * amount of requested nodes and the task to be used, in order to
209 * construct the tasks graph.
210 * @param spawnerIP IP of the requester
211 * @param nbTasks Amount of tasks
212 * @param t Tasks to be executed
213 * @param nbNoeuds Total amount of requested nodes
214 * @param algo Identifier of the mapping algorithm
215 * @param paramAlgo Parameter of the mapping algorithm
217 * @author Sébastien Miquée
220 public Register getRegisterSpawner(String spawnerIP, int nbTasks, Task t,
221 int nbNoeuds, int algo, double paramAlgo) throws RemoteException {
223 // Have we the correct application ?
225 System.err.println( "Problem of class transmission!" ) ;
229 if( t.getDependencies( 0 ) == null )
231 System.err.println( "No redifinition of getDependencies() function!" ) ;
236 /** Creation of an empty new Register **/
237 Register reg = new Register() ;
241 /** Initialization of Grid architecture (G5K for now) **/
242 Grid grid = Utils.createGridG5k(gnodes);
243 // grid.initClusters();
246 /** Informing about the grid heterogeneity **/
247 System.out.println( "\nHeterogeneity of the grid : " + grid.getHeterogenityDegre() + "\n" ) ;
250 /** Creation of tasks GTask **/
251 ArrayList<GTask> ts = new ArrayList<GTask>();
252 for( int i = 0; i < nbTasks; i++ ) {
253 ts.add( new GTask( i ) ) ;
256 /** Research of dependencies **/
257 for( int i = 0; i < nbTasks; i++ ) {
259 dep = t.getDependencies( i ) ;
261 /** Adding dependencies to tasks **/
262 for( int j = 0; j < dep.length; j++ ) {
264 ts.get( i ).addDependance( ts.get( dep[ j ] ) ) ;
271 /** Creation of the application interaction graph **/
272 Graph graph = new Graph();
274 for( int i = 0 ; i < ts.size() ; i++)
276 graph.addGTask(ts.get(i));
283 // Thread.sleep(10000) ;
284 // } catch( Exception e ) {}
289 // Thread.sleep( 10000 ) ;
290 // } catch( Exception e ) {}
292 /** Selection of the mapping algorithm **/
297 al = new Simple(graph, grid);
300 al = new QM(graph, grid, paramAlgo);
303 al = new LSM(graph, grid, paramAlgo);
306 al = new DefaultMapping( graph, grid, gnodes ) ;
311 /** Launching the Mapping **/
315 /** Creating the register **/
316 ArrayList<GNode> ag = al.getMapping().getMappedGNodes();
320 for( int i = 0; i < ag.size(); i++ ) {
321 reg.addNode((Node) ag.get(i).getNode());
322 delGNodeFromList( (Node) ag.get(i).getNode(), 2, spawnerIP ) ;
323 // gnodes.remove(ag.get(i));
324 // Register.Instance().removeNode((Node) ag.get(i).getNode());
328 /** Searching extra nodes if any **/
329 if( nbNoeuds > nbTasks )
331 int nb = nbNoeuds - nbTasks ;
334 for( int i = 0 ; i < nb ; i ++ )
336 sup = al.getOtherGNode( gnodes ) ;
337 reg.addNodeBeg( (Node) sup.getNode() ) ;
338 delGNodeFromList( (Node) sup.getNode(), 2, spawnerIP ) ;
344 if (ag.size() != 0) {
345 SuperNodeListe.Instance().forwardCountNode();
348 /** Setting the algorithm's identifier **/
349 al.setIdS( spawnerIP ) ;
351 /** Adding the algorithm in the list **/
356 // System.out.println( "Spawner returned reg: " + reg ) ;
358 /** Mapping distribution over other SuperNodes */
359 SuperNodeListe.Instance().setMapping( al ) ;
363 /** Returning result **/
369 * Suppress a node from the gnodes list if this node is free, or remove
370 * it from the Mapping class of the mapping algorithm if this node is
371 * a computation node. After having done the local suppression of the node
372 * it propagates the suppression to other SuperNodes.
373 * @param _n The fallen node
374 * @param _mode Choice of the list (0: gnodes, 1: mapping, 2:just mapped)
376 * @author Sébastien Miquée
379 public GNode delGNodeFromList( Node _n, int _mode, String _spawnerIp ) throws RemoteException
381 GNode removedGNode = null ;
385 boolean free = false ;
393 /** The dead node is not in the mapping **/
394 if( _mode == 0 || _mode == 2)
396 for( int i = 0 ; i < gnodes.size() ; i++ )
398 if( ((Node)gnodes.get(i).getNode()).getId() == _n.getId() )
400 removedGNode = gnodes.remove( i ) ;
401 Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
407 /** The dead node is in the mapping **/
410 /** Searching the algorithm **/
411 int idAlgo = searchAlgo( _spawnerIp ) ;
415 System.err.println( "No algorithm found for this Spawner!" ) ;
419 ArrayList<GNode> temp = algos.get( idAlgo ).getMapping().getMappedGNodes() ;
421 for( int i = 0 ; i < temp.size() ; i++ )
423 if( ((Node)temp.get(i).getNode()).getId() == _n.getId() )
425 removedGNode = temp.get( i ) ;
426 Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
432 /** Removing the dead node from the Grid **/
433 if( _mode == 0 || _mode == 1 ) {
434 int idAlgo = searchAlgo( _spawnerIp ) ;
436 if( idAlgo != -1 && _mode == 1 )
438 algos.get( idAlgo ).getGrid().removeGNode( removedGNode ) ;
442 /** Propagation of the deletion **/
443 SuperNodeListe.Instance().removeGNode( removedGNode, _mode, _spawnerIp ) ;
452 return removedGNode ;
457 * Search the position of the mapping algorithm in the list.
458 * @param _id Identifier of the algorithm
459 * @return The position in the list
461 private int searchAlgo( String _id )
465 for( int i = 0 ; i < algos.size() ; i++ )
467 if( algos.get( i ).getIdS().equals( _id ) )
478 * Determine if this SuperNode can operate on the gnodes list.
479 * It asks other SuperNodes to know if their are working on this list
480 * and set the authorization, or not.
482 * @author Sébastien Miquée
484 private void workingOnGnodes()
496 tmp = tmp && SuperNodeListe.Instance().workingOnGnodes() ;
506 } catch (InterruptedException e) {
516 * Search and return a new node when one failed or when JaceP2P needs another
517 * one. For the first case, the given failed node should not be null, and
518 * null in the other case.
519 * @param _spawnerIP IP of the requester
520 * @param _deadNode The failed node
522 * @author Sébastien Miquée
525 public Node getNewNode( String _spawnerIP, Node _deadNode ) throws RemoteException
528 GNode remp = null, gnode = null ;
530 int idAlgo = searchAlgo( _spawnerIP ) ;
534 System.err.println( "No algorithm found for this Spawner!" ) ;
538 /** Can we use gnodes ?**/
541 if( _deadNode != null )
545 gnode = delGNodeFromList( _deadNode, 1, _spawnerIP ) ;
547 remp = algos.get( idAlgo ).replaceNode( gnode, gnodes ) ;
551 System.out.println( "Replacing node found." ) ;
553 remp.setMapped( true ) ;
555 delGNodeFromList( (Node) remp.getNode(), 2, _spawnerIP ) ;
559 SuperNodeListe.Instance().forwardCountNode();
561 System.err.println( "Replacing node not found !!" ) ;
564 remp = algos.get( idAlgo ).getOtherGNode( gnodes ) ;
568 System.out.println( "Other new node found." ) ;
570 remp.setMapped( true ) ;
574 delGNodeFromList( (Node) remp.getNode(), 2, _spawnerIP ) ;
578 SuperNodeListe.Instance().forwardCountNode();
580 System.err.println( "Other new node not found !!" ) ;
586 node = (Node) remp.getNode() ;
590 /** Updating all mapping **/
591 updateMappedNode( gnode, remp, _spawnerIP ) ;
592 propagateReplaceNode( gnode, remp, _spawnerIP ) ;
595 /** Free the gnodes use **/
603 * Replace a failed GNode in the mapping by another one.
604 * This method is called by the SuperNodeList, to broadcast the modification.
605 * @param _dead The failed node
606 * @param _remp The replacing node
608 * @author Sébastien Miquée
611 public void updateMappedNode( GNode _dead, GNode _remp, String _spawnerIP )
617 int idAlgo = searchAlgo( _spawnerIP ) ;
621 System.err.println( "No algorithm found for this Spawner!" ) ;
625 pos = algos.get( idAlgo ).getMapping().getIdOfAssociation( _dead ) ;
629 /** Changing the node in the mapping **/
630 algos.get( idAlgo ).getMapping().getMapping().get( pos ).setGNode( _remp ) ;
632 System.out.println( "Succesfully replacing the fallen node in the mapping." ) ;
635 /** Changing the status in the grid **/
636 algos.get( idAlgo ).getGrid().setMappedStatus( _remp, true ) ;
638 algos.get( idAlgo ).updateGrid() ;
640 System.err.println( "The new GNode is null!" ) ;
646 * Inform all SuperNodes of the replacement of a failed computing node.
647 * @param _dead The failed node
648 * @param _remp The replacing node
650 * @author Sébastien Miquée
652 private void propagateReplaceNode( GNode _dead, GNode _remp, String _spawnerIP ) throws RemoteException
656 SuperNodeListe.Instance().propagateReplaceNode( _dead, _remp, _spawnerIP ) ;
660 /**********************************************************/
661 /**********************************************************/
666 * Add a new node in the list.
667 * @param _g The new node
669 * @author Sébastien Miquée
671 public void addGNode( GNode _g ) throws RemoteException
675 boolean free = false ;
692 // public void removeGNode( GNode _g ) throws RemoteException
696 // boolean free = false ;
700 // workingOnGnodes() ;
704 // for( int i = 0 ; i < gnodes.size() ; i++ )
706 // if( ((Node)gnodes.get(i).getNode()).getId() == ((Node)_g.getNode()).getId() )
708 // gnodes.remove( i ) ;
709 // Register.Instance().removeNodeOfName( _g.getName() ) ;
715 // operating = false ;
722 * Set the local mapping with another done on an other SuperNode.
723 * @param _al The new mapping
725 * @author Sébastien Miquée
728 public void setMapping( Algo _al ) throws RemoteException
730 if( searchAlgo( _al.getIdS() ) == -1 )
737 * Allow or deny the use of operations on the gnodes list, in order to
738 * do a mapping operation.
739 * @return The authorization or not to block gnodes
741 * @author Sébastien Miquée
743 public boolean blockForMapping() throws RemoteException
749 } catch (InterruptedException e) {
754 if( operating && ! authorized )
763 * Return the array containing the current not mapped nodes available.
764 * @return The array of available nodes
766 * @author Sébastien Miquée
769 public ArrayList<GNode> getGNodes() throws RemoteException
776 * Remove a mapping algorithm of the algorithms list.
777 * @param _id The algorithm identifier
778 * @param _mode Indicate if the information should be transmitted
780 * @author Sébastien Miquée
782 public void removeAlgo( String _id, int _mode ) throws RemoteException
786 i = searchAlgo( _id ) ;
794 SuperNodeListe.Instance().removeAlgo( _id ) ;