Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Correction of the grid status update.
[jaceP2P.git] / src / jaceP2P / JaceSuperNodeServer.java
1 package jaceP2P;
2
3 import java.rmi.RemoteException;
4 import java.rmi.server.UnicastRemoteObject;
5 import java.util.ArrayList;
6 import java.util.Vector;
7
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;
18
19
20 public class JaceSuperNodeServer extends UnicastRemoteObject implements
21                 JaceSuperNodeInterface {
22         private static final long serialVersionUID = 1L;
23
24         // Attributes
25         private int beat;
26         private ArrayList<GNode> gnodes = null;
27         private Algo al = null ;
28         private int count = 0 ;
29         private boolean inDemand = false, operating = false, authorized = false ;
30 //      private boolean daemonListChange ;
31         
32         // Constructors
33
34         public JaceSuperNodeServer(int timeBeat) throws RemoteException {
35                 super() ;
36                 beat = timeBeat ;
37                 gnodes = new ArrayList<GNode>() ;
38 //              daemonListChange = true ;
39         }
40
41         public int getSuperNodeBeat() throws RemoteException {
42                 return beat;
43         }
44
45         public Vector<?> sendStub(String IP, int port, JaceSuperNodeInterface stub)
46                         throws RemoteException {
47                 SuperNodeListe.Instance().addStubOf(IP, port, stub);
48                 System.out.println("Added new superNode (" + IP
49                                 + ") to list and return List");
50                 return SuperNodeListe.Instance().getListe();
51         }
52
53         public void updateCountNode(String IP, int nb) throws RemoteException {
54                 SuperNodeListe.Instance().modifCountNode(IP, nb);
55                 // System.out.println( "SuperNode " + IP + " has registered " + nb +
56                 // " Daemons" ) ;
57                 SuperNodeListe.Instance().viewAll();
58         }
59
60         public void sendSurplus(Vector<?> nodes, ArrayList<GNode> _gnodes) throws RemoteException {
61                 System.out.println("Recieved " + nodes.size() + " nodes");
62
63                 for (int i = 0; i < nodes.size(); i++) {
64                         Register.Instance().getListe().add((Node) nodes.elementAt(i));
65
66                         System.out.println("Adding "
67                                         + ((Node) nodes.elementAt(i)).getName());
68
69                         try {
70                                 ((Node) nodes.elementAt(i)).getStub().updateHeart(
71                                                 LocalHost.Instance().getSuperNodeStub());
72                                 int index = SuperNodeListe.Instance().existSuperNode(
73                                                 LocalHost.Instance().getIP());
74                                 ((SuperNodeData) SuperNodeListe.Instance().getListe()
75                                                 .get(index))
76                                                 .setNbOfNodes(Register.Instance().getSize());
77                                 new ForwardCount().start();
78                         } catch (Exception e) {
79                                 System.err.println("Error changing Server in SendSurplus : "
80                                                 + e);
81                         }
82                 }
83                 
84                 /** Updating gnodes **/
85                 if( _gnodes != null )
86                 {
87                         gnodes = _gnodes ;
88                 }
89         }
90
91         public void setToken() throws RemoteException {
92                 System.out.println("I got Token");
93
94                 TokenThread.Instance().setToken();
95
96                 try {
97                         HeartBeatSNode.Instance().getServer().beating(true);
98
99                         System.out.println("Put token to true");
100                 } catch (Exception e) {
101                         System.err
102                                         .println("Unable to heartBeat the next SuperNode with the new Token : "
103                                                         + e);
104                 }
105         }
106
107         public void updateHeart(JaceSuperNodeInterface stub) throws RemoteException {
108                 System.out.println("I change to ping a superNode");
109
110                 HeartBeatSNode.Instance().setServer(stub);
111         }
112
113         public synchronized void removeSuperNode(SuperNodeData d)
114                         throws RemoteException {
115                 SuperNodeListe.Instance().removeSuperNode(d);
116         }
117
118         /****************************************************/
119         /****************************************************/
120
121         // Register a Daemon in the Register.Instance() of the SuperNode
122         public synchronized void workerRegistering(JaceInterface workerStub,
123                         String workerIP, String workerName, int port, GNode g)
124                         throws RemoteException {
125                 System.out.println("CONNECTION of " + workerName);
126
127                 // Create the node
128                 Node noeud = new Node(workerStub);
129                 noeud.setName(workerName);
130                 noeud.setIP(workerIP);
131                 noeud.setAliveFlag(true);
132                 noeud.setAliveTime();
133                 noeud.setPort(port);
134                 noeud.setAppliName(null);
135                 noeud.setNbOfBeats(0);
136                 noeud.setId( count ) ;
137                 noeud.setId( Long.parseLong( workerIP.replace( ".", "" ) ) ) ;
138
139                 g.setNode( noeud ) ;
140                 g.setId( noeud.getId() ) ;
141                 g.setMapped( false ) ;
142                 
143                 workingOnGnodes() ;
144                 
145                 gnodes.add( g ) ;
146                 
147 //              daemonListChange = true ;
148
149                 // Insert the node in the Register.Instance() of the Super Node
150                 Register.Instance().addNode(noeud);
151
152                 // Register.Instance().viewAll() ;
153                 // SuperNodeListe.Instance().viewAll() ;
154
155                 // Inform the other superNode and tell them the nb of Daemon I have
156                 // registered
157                 int index = SuperNodeListe.Instance().existSuperNode(
158                                 LocalHost.Instance().getIP());
159
160                 ((SuperNodeData) SuperNodeListe.Instance().getListe().get(index))
161                                 .setNbOfNodes(Register.Instance().getSize());
162                 SuperNodeListe.Instance().forwardCountNode();
163                 
164                 authorized = true ;
165                 SuperNodeListe.Instance().addGNode( g ) ;
166                 authorized = false ;
167                 
168                 operating = false ;
169         }
170
171         /****************************************************/
172         /****************************************************/
173
174         // HeartBeat that detects if a Daemon is dead or alive
175         public void beating(JaceInterface stub) throws RemoteException {
176                 Node noeud = Register.Instance().getNodeOfStub(stub);
177
178                 if (noeud != null) {
179                         noeud.setAliveFlag(true);
180                         noeud.setAliveTime();
181                         noeud.incrementNbOfBeats();
182                         // -- sm modif
183                         // System.out.println( noeud.getName() + " is pinging me" ) ;
184                 } else {
185                         // System.out.println( noeud.getName() +
186                         // ".................. is not in my list" ) ;
187                 }
188         }
189
190         // HeartBeat that detects if a Super Node is dead or alive
191         public void beating(boolean token) throws RemoteException {
192                 ScanThreadSuperNode.Instance().setAliveTime();
193                 ScanThreadSuperNode.Instance().setToken(token);
194                 // -- sm modif
195                 // System.out.println( "Super Node is pinging me" ) ;
196         }
197
198
199         /*********************************/
200         /** Mapping !! Sébastien Miquée **/
201         /*********************************/
202
203         /**
204          * Search and return to the requester spawner a register containing
205          * computation nodes plus some extra nodes if needed. This method requires
206          * as parameters the mapping algorithm choice and its parameters, and the
207          * amount of requested nodes and the task to be used, in order to 
208          * construct the tasks graph.
209          * @param spawnerIP IP of the requester
210          * @param nbTasks Amount of tasks
211          * @param t Tasks to be executed
212          * @param nbNoeuds Total amount of requested nodes
213          * @param algo Identifier of the mapping algorithm
214          * @param paramAlgo Parameter of the mapping algorithm 
215          * 
216          * @author S&eacute;bastien Miqu&eacute;e        
217          */
218         @Override
219         public Register getRegisterSpawner(String spawnerIP, int nbTasks, Task t,
220                         int nbNoeuds, int algo, double paramAlgo) throws RemoteException {
221
222                 // Have we the correct application ?
223                 if (t == null) {
224                         System.err.println( "Problem of class transmission !" ) ;
225                         return null ;
226                 }
227                 
228                 if( t.getDependencies( 0 ) == null )
229                 {
230                         System.err.println( "No redifinition of getDependencies() functions !" ) ;
231                         return null ;
232                 }
233                 
234
235                 /** Creation of an empty new Register **/
236                 Register reg = new Register() ;
237
238                 workingOnGnodes() ;
239                 
240                 /** Initialization of Grid architecture (G5K for now) **/
241                 Grid grid = Utils.createGridG5k(gnodes);
242 //              grid.initClusters();
243                 
244
245                 /** Creation of tasks GTask **/
246                 ArrayList<GTask> ts = new ArrayList<GTask>();
247                 for (int i = 0; i < nbTasks; i++) {
248                         ts.add(new GTask( i ) ) ;
249                 }
250
251                 /** Research of dependencies **/
252                 for (int i = 0; i < nbTasks; i++) {
253                         int dep[] = null;
254                         dep = t.getDependencies(i);
255
256                         /** Adding dependencies to tasks **/
257                         for (int j = 0; j < dep.length; j++) {
258                                 if (dep[j] != -1) {
259                                         ts.get(i).addDependance(ts.get(dep[j]));
260                                 } else {
261                                         break;
262                                 }
263                         }
264                 }
265                 
266
267                 Graph graph = new Graph();
268
269                 for( int i = 0 ; i < ts.size() ; i++) 
270                 {
271                         graph.addGTask(ts.get(i));
272                 }
273
274                 // -- debug !
275                 // graph.print() ;
276
277                 // try {
278                 // Thread.sleep(10000) ;
279                 // } catch( Exception e ) {}
280
281                 // grid.print() ;
282                 // 
283                 // try {
284                 // Thread.sleep( 10000 ) ;
285                 // } catch( Exception e ) {}
286
287                 /** Selection of the mapping algorithm **/
288                 al = null ;
289
290                 switch (algo) {
291                 case 0:
292                         al = new Simple(graph, grid);
293                         break;
294                 case 1:
295                         al = new QM(graph, grid, paramAlgo);
296                         break;
297                 case 2:
298                         al = new LSM(graph, grid, paramAlgo);
299                         break;
300                 default:
301                         al = new DefaultMapping( graph, grid, gnodes ) ;
302                 }
303
304                 if (al != null) {
305                         /** Launching the Mapping **/
306                         al.map();
307
308
309                         /** Creating the register **/
310                         ArrayList<GNode> ag = al.getMapping().getMappedGNodes();
311
312                         authorized = true ;
313                         
314                         for( int i = 0; i < ag.size(); i++ ) {
315                                 reg.addNode((Node) ag.get(i).getNode());
316                                 delGNodeFromList( (Node) ag.get(i).getNode(), 2 ) ;
317 //                              gnodes.remove(ag.get(i));
318 //                              Register.Instance().removeNode((Node) ag.get(i).getNode());
319                         }
320                         
321                         
322                         /** Searching extra nodes if any **/
323                         if( nbNoeuds > nbTasks )
324                         {
325                                 int nb = nbNoeuds - nbTasks ;
326                                 GNode sup = null ;
327                                 
328                                 for( int i = 0 ; i < nb ; i ++ )
329                                 {
330                                         sup = al.getOtherGNode( gnodes ) ;
331                                         reg.addNodeBeg( (Node) sup.getNode() ) ;
332                                         delGNodeFromList( (Node) sup.getNode(), 2 ) ;
333                                 }
334                         }
335                         
336                         authorized = false ;
337
338                         if (ag.size() != 0) {
339                                 SuperNodeListe.Instance().forwardCountNode();
340                         }
341
342                 } 
343                 
344 //              System.out.println( "Spawner returned reg: " + reg ) ;
345                 
346                 /** Mapping distribution over other SuperNodes */
347                 SuperNodeListe.Instance().setMapping( al ) ;
348                 
349                 operating = false ;
350                 
351                 /** Returning result **/
352                 return reg ;
353         }
354
355         
356         /**
357          * Suppress a node from the gnodes list if this node is free, or remove
358          * it from the Mapping class of the mapping algorithm if this node is
359          * a computation node. After having done the local suppression of the node
360          * it propagates the suppression to other SuperNodes.
361          * @param _n The fallen node
362          * @param _mode Choice of the list (0: gnodes, 1: mapping, 2:just mapped)
363          * 
364          * @author S&eacute;bastien Miqu&eacute;e        
365          */
366         @Override
367         public GNode delGNodeFromList( Node _n, int _mode ) throws RemoteException
368         {
369                 GNode removedGNode = null ;
370                 
371                 if( _n != null )
372                 {       
373                         boolean free = false ;
374                         
375                         if( ! operating )
376                         {
377                                 workingOnGnodes() ;
378                                 free = true ;
379                         }
380                         
381                         /** The dead node is not in the mapping **/
382                         if( _mode == 0 || _mode == 2)
383                         {
384                                 for( int i = 0 ; i < gnodes.size() ; i++ )
385                                 {
386                                         if( ((Node)gnodes.get(i).getNode()).getId() == _n.getId() ) 
387                                         {
388                                                 removedGNode = gnodes.remove( i ) ;
389                                                 Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
390                                                 break ;
391                                         }
392                                 }
393                         }
394                         
395                         /** The dead node is in the mapping **/
396                         if( _mode == 1 )
397                         {
398                                 ArrayList<GNode> temp = al.getMapping().getMappedGNodes() ;
399                                 
400                                 for( int i = 0 ; i < temp.size() ; i++ )
401                                 {
402                                         if( ((Node)temp.get(i).getNode()).getId() == _n.getId() ) 
403                                         {
404                                                 removedGNode = temp.get( i ) ;
405                                                 Register.Instance().removeNodeOfName( removedGNode.getName() ) ;
406                                                 break ;
407                                         }
408                                 }       
409                         }
410                         
411                         /** Removing the dead node from the Grid **/
412                         if( _mode == 0 || _mode == 1 ) {
413                                 al.getGrid().removeGNode( removedGNode ) ;
414                         }
415                         
416                         /** Propagation of the deletion **/
417                         SuperNodeListe.Instance().removeGNode( removedGNode, _mode ) ;
418                         
419                         if( free )
420                         {
421                                 operating = false ;
422                         }
423                 
424                 }
425                 
426                 return removedGNode ;
427         }
428         
429         
430         /**
431          * Determine if this SuperNode can operate on the gnodes list.
432          * It asks other SuperNodes to know if their are working on this list
433          * and set the authorization, or not.
434          * 
435          * @author S&eacute;bastien Miqu&eacute;e        
436          */
437         private void workingOnGnodes()
438         {
439                 boolean tmp = true ;    
440                 
441                 inDemand = false ; 
442                 operating = false ;
443             
444                 while( ! operating )
445                 {
446                         inDemand = true ;
447                         tmp = true ;
448                         
449                         tmp = tmp && SuperNodeListe.Instance().workingOnGnodes() ;
450
451                         operating = tmp ;
452                         
453                         if( ! tmp )
454                         {
455                                 inDemand = false ;
456                                 
457                                 try {
458                                         Thread.sleep( 10 ) ;
459                                 } catch (InterruptedException e) {
460                                         e.printStackTrace();
461                                 }
462                         }
463                 }
464                 
465                 inDemand = false ;
466         }
467
468         /**
469          * Search and return a new node when one failed or when JaceP2P needs another
470          * one. For the first case, the given failed node should not be null, and
471          * null in the other case.
472          * @param _spawnerIP IP of the requester
473          * @param _deadNode The failed node
474          * 
475          * @author S&eacute;bastien Miqu&eacute;e
476          */
477         @Override
478         public Node getNewNode( String _spawnerIP, Node _deadNode ) throws RemoteException
479         {
480                 Node node = null ;
481                 GNode remp = null, gnode = null ;
482                 
483                 /** Can we use gnodes ?**/
484                 workingOnGnodes() ;
485                 
486                 if( _deadNode != null )
487                 {
488                         authorized = true ;
489                         
490                         gnode = delGNodeFromList( _deadNode, 1 ) ;
491
492                         remp = al.replaceNode( gnode, gnodes ) ;
493                 
494                         if( remp != null )
495                         {
496                                 System.out.println( "Replacing node found." ) ;
497                                 
498                                 remp.setMapped( true ) ;
499                                 
500                                 delGNodeFromList( (Node) remp.getNode(), 2 ) ;
501                                 
502                                 /** Updating all mapping **/
503                                 updateMappedNode( gnode, remp ) ;
504                                 propagateReplaceNode( gnode, remp ) ;
505                                 
506                                 authorized = false ;
507                                 
508                                 SuperNodeListe.Instance().forwardCountNode();
509                         } else {
510                                 System.err.println( "Replacing node not found !!" ) ;
511                         }
512                 } else {
513                         remp = al.getOtherGNode( gnodes ) ;
514                         
515                         if( remp != null )
516                         {
517                                 System.out.println( "Other new node found." ) ;
518
519                                 authorized = true ;
520                                 
521                                 delGNodeFromList( (Node) remp.getNode(), 2 ) ;
522                                 
523                                 authorized = false ;
524                                 
525                                 SuperNodeListe.Instance().forwardCountNode();
526                         } else {
527                                 System.err.println( "Other new node not found !!" ) ;
528                         }
529                 }
530                 
531                 /** Free the gnodes use **/
532                 operating = false ;
533                 
534                 return node ;
535         }
536         
537         
538         /**
539          * Replace a failed GNode in the mapping by another one.
540          * This method is called by the SuperNodeList, to broadcast the modification.
541          * @param _dead The failed node
542          * @param _remp The replacing node
543          * 
544          * @author S&eacute;bastien Miqu&eacute;e
545          */
546         @Override
547         public void updateMappedNode( GNode _dead, GNode _remp ) 
548         {
549                 if( _dead != null )
550                 {
551                         int pos = 0 ;
552                 
553                         pos = al.getMapping().getIdOfAssociation( _dead ) ;
554                 
555                         if( pos != -1 )
556                         {
557                                 /** Changing the node in the mapping **/
558                                 al.getMapping().getMapping().get( pos ).setGNode( _remp ) ;
559                                 
560                                 System.out.println( "Succesfully replacing the fallen node in the mapping." ) ;
561                         }               
562                         
563                         /** Changing the status in the grid **/
564                         al.getGrid().setMappedStatus( _remp, true ) ;
565                 
566                         al.updateGrid() ;
567                 } else {
568                         System.err.println( "GNode "+_dead+" does not exist in the mapping!" ) ;
569                 }
570         }
571
572         
573         /**
574          * Inform all SuperNodes of the replacement of a failed computing node.
575          * @param _dead The failed node
576          * @param _remp The replacing node
577          * 
578          * @author S&eacute;bastien Miqu&eacute;e        
579          */
580         private void propagateReplaceNode( GNode _dead, GNode _remp ) throws RemoteException
581         {
582                 if( _dead != null && _remp != null )
583                 {       
584                         SuperNodeListe.Instance().propagateReplaceNode( _dead, _remp ) ;
585                 }
586         }
587
588         /**********************************************************/
589         /**********************************************************/
590
591         
592         @Override
593         /**
594          * Add a new node in the list.
595          * @param _g The new node
596          *
597          * @author S&eacute;bastien Miqu&eacute;e        
598          */
599         public void addGNode( GNode _g ) throws RemoteException 
600         {
601                 if( _g != null )
602                 {
603                         boolean free = false ;
604                         
605                         if( ! operating )
606                         {
607                                 workingOnGnodes() ;
608                                 free = true ;
609                         }       
610                         
611                         gnodes.add( _g ) ;
612                         
613                         if( free )
614                                 operating = false ;
615                 }
616         }
617         
618
619 //      @Override
620 //      public void removeGNode( GNode _g ) throws RemoteException 
621 //      {
622 //              if( _g != null )
623 //              {
624 //                      boolean free = false ;
625 //                      
626 //                      if( ! operating )
627 //                      {
628 //                              workingOnGnodes() ;
629 //                              free = true ;
630 //                      }
631 //                      
632 //                      for( int i = 0 ; i < gnodes.size() ; i++ )
633 //                      {
634 //                              if( ((Node)gnodes.get(i).getNode()).getId() == ((Node)_g.getNode()).getId() ) 
635 //                              {
636 //                                      gnodes.remove( i ) ;
637 //                                      Register.Instance().removeNodeOfName( _g.getName() ) ;
638 //                                      break ;
639 //                              }
640 //                      }
641 //                      
642 //                      if( free )
643 //                              operating = false ;
644 //              }
645 //              
646 //      }
647         
648
649         /**
650          * Set the local mapping with another done on an other SuperNode.
651          * @param _al The new mapping
652          * 
653          * @author S&eacute;bastien Miqu&eacute;e
654          */
655         @Override
656         public void setMapping( Algo _al ) throws RemoteException 
657         {
658                 al = _al ;              
659         }
660
661         
662         @Override
663         /**
664          * Allow or deny the use of operations on the gnodes list, in order to
665          * do a mapping operation.
666          * @return The authorization or not to block gnodes
667          * 
668          * @author S&eacute;bastien Miqu&eacute;e
669          */
670         public boolean blockForMapping() throws RemoteException
671         {
672                 while( inDemand )
673                 {
674                         try {
675                                 Thread.sleep( 10 ) ;
676                         } catch (InterruptedException e) {
677                                 e.printStackTrace();
678                         }
679                 }
680                 
681                 if( operating && ! authorized )
682                 {
683                         return false ;
684                 } else {
685                         return true ;
686                 }
687         }
688
689         /**
690          * Return the array containing the current not mapped nodes available.
691          * @return The array of available nodes
692          * 
693          * @author S&eacute;bastien Miqu&eacute;e 
694          */
695         @Override
696         public ArrayList<GNode> getGNodes() throws RemoteException 
697         {
698                 return gnodes ;
699         }
700         
701 }
702
703 /** ! **/