3 import java.rmi.RemoteException;
4 import java.rmi.server.UnicastRemoteObject;
5 import java.util.ArrayList;
7 import and.Mapping.Algo;
8 import and.Mapping.DefaultMapping;
9 import and.Mapping.FT_AIAC_QM;
10 import and.Mapping.FT_FEC;
11 import and.Mapping.GNode;
12 import and.Mapping.GTask;
13 import and.Mapping.Graph;
14 import and.Mapping.Grid;
15 import and.Mapping.Maheve;
16 import and.Mapping.Simple;
19 public class JaceSuperNodeServer extends UnicastRemoteObject implements
20 JaceSuperNodeInterface {
21 private static final long serialVersionUID = 1L;
25 private ArrayList<GNode> gnodes = null;
26 private ArrayList<Algo> algos = null ;
27 private boolean inDemand = false, operating = false, authorized = false ;
31 public JaceSuperNodeServer(int timeBeat) throws RemoteException {
34 gnodes = new ArrayList<GNode>() ;
35 algos = new ArrayList<Algo>() ;
38 public int getSuperNodeBeat() throws RemoteException {
42 public ArrayList<Object> sendStub(String IP, int port, JaceSuperNodeInterface stub)
43 throws RemoteException {
44 SuperNodeListe.Instance().addStubOf(IP, port, stub);
45 System.out.println("Added new superNode (" + IP
46 + ") to list and return List");
47 return SuperNodeListe.Instance().getListe() ;
50 public void updateCountNode(String IP, int nb) throws RemoteException {
51 SuperNodeListe.Instance().modifCountNode(IP, nb);
52 // System.out.println( "SuperNode " + IP + " has registered " + nb +
54 SuperNodeListe.Instance().viewAll();
57 public void sendSurplus(ArrayList<Node> nodes, ArrayList<GNode> _gnodes) throws RemoteException {
58 System.out.println("Recieved " + nodes.size() + " nodes");
60 for (int i = 0; i < nodes.size(); i++) {
61 Register.Instance().getListe().add((Node) nodes.get(i));
63 System.out.println("Adding "
64 + ((Node) nodes.get(i)).getName());
67 ((Node) nodes.get(i)).getStub().updateHeart(
68 LocalHost.Instance().getSuperNodeStub());
69 int index = SuperNodeListe.Instance().existSuperNode(
70 LocalHost.Instance().getIP());
71 ((SuperNodeData) SuperNodeListe.Instance().getListe()
73 .setNbOfNodes(Register.Instance().getSize());
74 new ForwardCount().start();
75 } catch (Exception e) {
76 System.err.println("Error changing Server in SendSurplus : "
81 /** Updating gnodes **/
88 public void setToken() throws RemoteException {
89 System.out.println("I got Token");
91 TokenThread.Instance().setToken();
94 HeartBeatSNode.Instance().getServer().beating(true);
96 System.out.println("Put token to true");
97 } catch (Exception e) {
99 .println("Unable to heartBeat the next SuperNode with the new Token : "
104 public void updateHeart(JaceSuperNodeInterface stub) throws RemoteException {
105 System.out.println("I change to ping a superNode");
107 HeartBeatSNode.Instance().setServer(stub);
110 public synchronized void removeSuperNode(SuperNodeData d)
111 throws RemoteException {
112 SuperNodeListe.Instance().removeSuperNode(d);
115 /****************************************************/
116 /****************************************************/
118 // Register a Daemon in the Register.Instance() of the SuperNode
119 public synchronized void workerRegistering(JaceInterface workerStub,
120 String workerIP, String workerName, int port, GNode g)
121 throws RemoteException {
122 System.out.println("CONNECTION of " + workerName);
125 Node noeud = new Node(workerStub);
126 noeud.setName(workerName);
127 noeud.setIP(g.getIP());
128 noeud.setAliveFlag(true);
129 noeud.setAliveTime();
131 noeud.setAppliName(null);
132 noeud.setNbOfBeats(0);
134 String sid = workerIP.replace( ".", "" ) + port ;
135 Long id = Long.parseLong( sid ) ;
140 g.setMapped( false ) ;
148 // Insert the node in the Register.Instance() of the Super Node
149 Register.Instance().addNode(noeud);
151 // Register.Instance().viewAll() ;
152 // SuperNodeListe.Instance().viewAll() ;
154 // Inform the other superNode and tell them the nb of Daemon I have
156 int index = SuperNodeListe.Instance().existSuperNode(
157 LocalHost.Instance().getIP());
159 ((SuperNodeData) SuperNodeListe.Instance().getListe().get(index))
160 .setNbOfNodes(Register.Instance().getSize());
161 SuperNodeListe.Instance().forwardCountNode();
164 SuperNodeListe.Instance().addGNode( g ) ;
172 * Update all mapping algorithms with a new node.
173 * @param _g The new node
175 * @author Sébastien Miquée
177 private synchronized void updateGrids( GNode _g )
181 for( int i = 0 ; i < algos.size() ; i++ )
183 algos.get( i ).getGrid().addGNode( _g ) ;
189 /****************************************************/
190 /****************************************************/
192 // HeartBeat that detects if a Daemon is dead or alive
193 public void beating(JaceInterface stub) throws RemoteException {
194 Node noeud = Register.Instance().getNodeOfStub(stub);
197 noeud.setAliveFlag(true);
198 noeud.setAliveTime();
199 noeud.incrementNbOfBeats();
201 // System.out.println( noeud.getName() + " is pinging me" ) ;
203 // System.out.println( noeud.getName() +
204 // ".................. is not in my list" ) ;
208 // HeartBeat that detects if a Super Node is dead or alive
209 public void beating(boolean token) throws RemoteException {
210 ScanThreadSuperNode.Instance().setAliveTime();
211 ScanThreadSuperNode.Instance().setToken(token);
213 // System.out.println( "Super Node is pinging me" ) ;
217 /*********************************/
218 /** Mapping !! Sébastien Miquée **/
219 /*********************************/
222 * Search and return to the requester spawner a register containing
223 * computation nodes plus some extra nodes if needed. This method requires
224 * as parameters the mapping algorithm choice and its parameters, and the
225 * amount of requested nodes and the task to be used, in order to
226 * construct the tasks graph.
227 * @param spawnerIP IP of the requester
228 * @param nbTasks Amount of tasks
229 * @param t Tasks to be executed
230 * @param nbNoeuds Total amount of requested nodes
231 * @param algo Identifier of the mapping algorithm
232 * @param paramAlgo Parameter of the mapping algorithm
234 * @author Sébastien Miquée
237 public synchronized Register getRegisterSpawner(String spawnerIP, int nbTasks, Task t,
238 int nbNoeuds, int algo, double paramAlgo) throws RemoteException {
240 // Have we the correct application ?
242 System.err.println( "Problem of class transmission!" ) ;
246 if( t.getDependencies( 0 ) == null )
248 System.err.println( "No redifinition of getDependencies() function!" ) ;
253 /** Creation of an empty new Register **/
254 Register reg = new Register() ;
258 /** Initialization of Grid architecture (G5K for now) **/
259 Grid grid = new Grid() ;
261 for( int i = 0 ; i < gnodes.size() ; i++ )
263 grid.addGNode( gnodes.get( i ) ) ;
267 /** Informing about the grid heterogeneity **/
268 System.out.println( "\nHeterogeneity degree of the grid: " + grid.getHeterogenityDegre() + "\n" ) ;
271 /** Creation of tasks GTask **/
272 ArrayList<GTask> ts = new ArrayList<GTask>();
273 for( int i = 0; i < nbTasks; i++ ) {
274 ts.add( new GTask( i ) ) ;
277 /** Research of dependencies **/
278 for( int i = 0; i < nbTasks; i++ ) {
280 dep = t.getDependencies( i ) ;
282 /** Adding dependencies to tasks **/
283 for( int j = 0; j < dep.length; j++ ) {
285 ts.get( i ).addDependance( ts.get( dep[ j ] ) ) ;
292 /** Creation of the application interaction graph **/
293 Graph graph = new Graph();
295 for( int i = 0 ; i < ts.size() ; i++)
297 graph.addGTask(ts.get(i));
300 /** TODO Loading algorithm class with parameters in a configuration file **/
301 /** Selection of the mapping algorithm **/
306 al = new Simple(graph, grid);
309 al = new FT_AIAC_QM(graph, grid, paramAlgo);
312 al = new FT_FEC(graph, grid, paramAlgo);
315 al = new Maheve( graph, grid ) ;
316 ((Maheve) al).setNbSave((int)paramAlgo);
319 al = new DefaultMapping( graph, grid ) ;
324 /** Launching the Mapping **/
328 /** Creating the register **/
329 ArrayList<GNode> ag = al.getMapping().getMappedGNodes();
331 System.out.println("NB returned nodes : "+ag.size());
334 /** Setting the algorithm's identifier **/
335 al.setIdS( spawnerIP ) ;
337 /** Adding the algorithm in the list **/
340 int idAlgo = searchAlgo( spawnerIP ) ;
342 /** Mapping distribution over other SuperNodes */
343 SuperNodeListe.Instance().setMapping( al ) ;
349 for( int i = 0; i < ag.size(); i++ ) {
350 reg.addNode((Node) ag.get(i).getNode());
352 ag.get(i).setMapped( true ) ;
353 setMapped( ag.get(i), 1 ) ;
354 Register.Instance().removeNode((Node) ag.get(i).getNode());
358 /** Searching extra nodes if any **/
359 if( nbNoeuds > nbTasks )
361 int nb = nbNoeuds - nbTasks ;
364 for( int i = 0 ; i < nb ; i ++ )
366 sup = algos.get(idAlgo).getOtherGNode( gnodes ) ;
367 algos.get(idAlgo).getMapping().addOtherNode( sup ) ;
368 reg.addNodeBeg( (Node) sup.getNode() ) ;
369 setMapped( sup, 1 ) ;
370 Register.Instance().removeNode((Node) sup.getNode());
376 if (ag.size() != 0) {
377 SuperNodeListe.Instance().forwardCountNode();
384 /** Returning result **/
389 public synchronized void setMapped( GNode _g, int _mode ) throws RemoteException
393 _g.setMapped( true ) ;
395 for( int i = 0 ; i < gnodes.size() ; i++ )
397 if( _g.getId() == gnodes.get( i ).getId() )
404 for( int i = 0 ; i < algos.size() ; i++ )
406 algos.get( i ).getGrid().setMappedStatus( _g, true ) ;
413 SuperNodeListe.Instance().setMappedGNode( _g, 0 ) ;
418 System.err.println( "GNode is null is setMapped!" ) ;
423 * Suppress a node from the gnodes list if this node is free, or remove
424 * it from the Mapping class of the mapping algorithm if this node is
425 * a computation node. After having done the local suppression of the node
426 * it propagates the suppression to other SuperNodes.
427 * @param _n The fallen node
428 * @param _mode Choice of the list (0: gnodes, 1: mapping, 2:just mapped)
430 * @author Sébastien Miquée
433 public synchronized GNode delGNodeFromList( Node _n, int _mode, String _spawnerIp ) throws RemoteException
435 GNode removedGNode = null ;
439 boolean free = false ;
451 for( int i = 0 ; i < gnodes.size() ; i++ )
453 if( _n.getId() == ((Node) gnodes.get(i).getNode()).getId() )
455 dead = gnodes.remove( i ) ;
462 for( int i = 0 ; i < algos.size() ; i++ )
464 algos.get( i ).getGrid().removeGNode( dead ) ;
465 Register.Instance().removeNodeOfName( dead.getName() ) ;
466 SuperNodeListe.Instance().removeGNode( dead, _mode, _spawnerIp ) ;
468 // trying to reboot the node
470 _n.getStub().suicide2( "Reboot!" ) ;
471 } catch( Exception e ) {
472 System.err.println( "(SN) Unable to reboot the node:" ) ;
473 e.printStackTrace() ;
477 System.err.println( "The dead node signaled does not exist!" ) ;
488 return removedGNode ;
493 * Search the position of the mapping algorithm in the list.
494 * @param _id Identifier of the algorithm
495 * @return The position in the list
497 private int searchAlgo( String _id )
501 for( int i = 0 ; i < algos.size() ; i++ )
503 if( algos.get( i ).getIdS().equals( _id ) )
514 * Determine if this SuperNode can operate on the gnodes list.
515 * It asks other SuperNodes to know if their are working on this list
516 * and set the authorization, or not.
518 * @author Sébastien Miquée
520 private synchronized void workingOnGnodes()
532 tmp = tmp && SuperNodeListe.Instance().workingOnGnodes() ;
542 } catch (InterruptedException e) {
552 * Search and return a new node when one failed or when JaceP2P needs another
553 * one. For the first case, the given failed node should not be null, and
554 * null in the other case.
555 * @param _spawnerIP IP of the requester
556 * @param _rank The task number number of the dead node
558 * @author Sébastien Miquée
561 public synchronized Node getNewNode( String _spawnerIP, int _rank ) throws RemoteException
564 int idAlgo = searchAlgo( _spawnerIP ) ;
568 System.err.println( "No algorithm found for this Spawner!" ) ;
572 /** We have to replace a Spawner **/
577 /** We have to replace a computing node **/
578 idNode = algos.get( idAlgo ).getMapping().getIdOfAssociation( _rank ) ;
583 System.err.println( "No tasks corresponds to rank "+_rank+"!" ) ;
591 dead = algos.get( idAlgo ).getMapping().getAssociation( idNode ).getGNode() ;
594 if( dead == null && idNode >= 0 )
596 System.err.println( "The GNode corresponding to the task "+_rank+" is null!" ) ;
597 System.err.println( "Trying to find a new node for this task (not optimal)..." ) ;
600 return getNewNode( _spawnerIP, dead ) ;
604 * Search and return a new node when one failed or when JaceP2P needs another
605 * one. For the first case, the given failed node should not be null, and
606 * null in the other case.
607 * @param _spawnerIP IP of the requester
608 * @param _deadNode The failed node
610 * @author Sébastien Miquée
613 public synchronized Node getNewNode( String _spawnerIP, GNode _deadNode ) throws RemoteException
618 int idAlgo = searchAlgo( _spawnerIP ) ;
622 System.err.println( "No algorithm found for this Spawner!" ) ;
627 /** Can we use gnodes ?**/
630 if( _deadNode != null )
634 removeMappedGNode( _deadNode, 1 ) ;
638 remp = algos.get( idAlgo ).replaceNode( _deadNode, gnodes ) ;
642 System.out.println( "Replacing node found." ) ;
646 remp.setMapped( true ) ;
648 setMapped( remp, 1 ) ;
649 Register.Instance().removeNodeOfName( remp.getName() ) ;
652 /** Updating all mapping **/
653 updateMappedNode( _deadNode, remp, _spawnerIP ) ;
654 propagateReplaceNode( _deadNode, remp, _spawnerIP ) ;
658 SuperNodeListe.Instance().forwardCountNode();
660 System.err.println( "Replacing node not found !!" ) ;
663 remp = algos.get( idAlgo ).getOtherGNode( gnodes ) ;
667 System.out.println( "Other new node found." ) ;
669 remp.setMapped( true ) ;
673 setMapped( remp, 1 ) ;
674 Register.Instance().removeNodeOfName( remp.getName() ) ;
678 SuperNodeListe.Instance().forwardCountNode();
680 System.err.println( "Other new node not found !!" ) ;
686 node = (Node) remp.getNode() ;
688 System.err.println( "SuperNode: No new node found!" ) ;
692 /** Free the gnodes use **/
699 public synchronized void removeMappedGNode( GNode _g, int _mode ) throws RemoteException
703 for( int i = 0 ; i < algos.size() ; i++ )
705 algos.get( i ).getGrid().removeGNode( _g ) ;
710 SuperNodeListe.Instance().removeGNode( _g, 0 ) ;
713 System.err.println( "GNode to be deleted is null!" ) ;
718 * Replace a failed GNode in the mapping by another one.
719 * This method is called by the SuperNodeList, to broadcast the modification.
720 * @param _dead The failed node
721 * @param _remp The replacing node
723 * @author Sébastien Miquée
726 public synchronized void updateMappedNode( GNode _dead, GNode _remp, String _spawnerIP )
732 int idAlgo = searchAlgo( _spawnerIP ) ;
736 System.err.println( "No algorithm found for this Spawner!" ) ;
740 pos = algos.get( idAlgo ).getMapping().getIdOfAssociation( _dead ) ;
744 /** Changing the node in the mapping **/
745 if( algos.get( idAlgo ).getMapping().getMapping().get( pos ).setGNode( _remp ) )
747 System.out.println( "Succesfully replacing the fallen node in the mapping." ) ;
749 System.err.println( "Failed in replacing the fallen node in the mapping!" ) ;
752 System.err.println( "The dead node was not found in the mapping!" ) ;
756 System.err.println( "The new GNode is null!" ) ;
762 * Inform all SuperNodes of the replacement of a failed computing node.
763 * @param _dead The failed node
764 * @param _remp The replacing node
766 * @author Sébastien Miquée
768 private synchronized void propagateReplaceNode( GNode _dead, GNode _remp, String _spawnerIP ) throws RemoteException
772 SuperNodeListe.Instance().propagateReplaceNode( _dead, _remp, _spawnerIP ) ;
774 System.err.println( "The replacement node is null!" ) ;
778 /**********************************************************/
779 /**********************************************************/
784 * Add a new node in the list.
785 * @param _g The new node
787 * @author Sébastien Miquée
789 public void addGNode( GNode _g ) throws RemoteException
793 boolean free = false ;
812 * Set the local mapping with another done on an other SuperNode.
813 * @param _al The new mapping
815 * @author Sébastien Miquée
818 public synchronized void setMapping( Algo _al ) throws RemoteException
820 if( searchAlgo( _al.getIdS() ) == -1 )
824 System.err.println( "I already have this mapping algorithm!" ) ;
831 * Allow or deny the use of operations on the gnodes list, in order to
832 * do a mapping operation.
833 * @return The authorization or not to block gnodes
835 * @author Sébastien Miquée
837 public boolean blockForMapping() throws RemoteException
843 } catch (InterruptedException e) {
848 if( operating && ! authorized )
857 * Return the array containing the current not mapped nodes available.
858 * @return The array of available nodes
860 * @author Sébastien Miquée
863 public ArrayList<GNode> getGNodes() throws RemoteException
870 * Remove a mapping algorithm of the algorithms list.
871 * @param _id The algorithm identifier
872 * @param _mode Indicate if the information should be transmitted
874 * @author Sébastien Miquée
876 public void removeAlgo( String _id, int _mode ) throws RemoteException
880 pos = searchAlgo( _id ) ;
884 algos.remove( pos ) ;
888 SuperNodeListe.Instance().removeAlgo( _id ) ;
891 System.err.println( "The mapping algorithm requested for deletion does not exist!" ) ;
897 public Algo getAlgo( String _spID ) throws RemoteException
902 pos = searchAlgo( _spID ) ;
906 ret = algos.get( pos ) ;