Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Correction of some bugs and performance enhancement.
[jaceP2P.git] / src / jaceP2P / BackupsManager.java
1 package jaceP2P;
2
3 import java.util.ArrayList;
4
5
6 public class BackupsManager {
7         final int MAX_COUNT_NOT_ALIVE = 3;
8
9         // attributes
10         public static BackupsManager Instance;
11         public int myRank = -1;
12         public ArrayList<Backup> liste = new ArrayList<Backup>();
13         public ArrayList<Backup> liste_Convg = new ArrayList<Backup>();
14
15         // constructors
16         private BackupsManager() {
17         }
18
19         public static BackupsManager Instance() {
20                 if (Instance == null) {
21                         Instance = new BackupsManager();
22                 }
23                 return Instance;
24         }
25
26         // retourne le nb de Backups ds la liste)
27         public synchronized int size() {
28                 return liste.size();
29         }
30
31         public synchronized void clean() {
32                 for (int i = 0; i < liste.size(); i++) {
33                         ((Backup) liste.get(i)).setIteration(-1);
34                         ((Backup) liste.get(i)).setData(null);
35                         ((Backup) liste_Convg.get(i)).setIteration(-1);
36                         ((Backup) liste_Convg.get(i)).setData(null);
37                 }
38         }
39
40         public synchronized void purge() {
41                 liste.clear();
42                 liste_Convg.clear();
43                 myRank = -1;
44                 Instance = null;
45         }
46
47         public synchronized int getMyRank() {
48                 return myRank;
49         }
50
51         public synchronized void initialize(int req) {
52                 ListeTask tskList = Register.Instance().getListeOfTasks();
53
54                 TaskId t = tskList.getTaskIdOfHostStub(LocalHost.Instance().getStub());
55                 if (t == null) {
56                         System.out.println("no corresponding task !!!!!!!!!!!!!!!!");
57                         // TODO
58                         // what can we do ?????????????????
59                 }
60                 myRank = t.getRank();
61                 int rankOfBackTask;
62
63                 // get the number of backup nodes there are for each task i
64                 int numBackNodes = Register.Instance().getNumBackupNeighbors();
65                 System.out.println("numBackNodes : " + numBackNodes);
66                 int numOfTasks = Register.Instance().getNbOfTasks();
67                 System.out.println("nombre de taches=" + numOfTasks);
68                 int tmp;
69                 int lastBackupRank;
70                 int lastBackupRankConv;
71
72                 // ****************************** STEP 1 : Create the empty
73                 // BackupsManager
74                 // **
75
76                 for (int i = 1; i <= numBackNodes; i++) {
77                         // ------------ 1 - for backups "i + n" (to the right of i)
78                         rankOfBackTask = (myRank + i) % numOfTasks;
79                         // System.out.println("i : " + i + ", rankOfBackTask : " +
80                         // rankOfBackTask);
81                         Backup b_right = new Backup(rankOfBackTask);
82                         addBackupTask(b_right, 0); // erase if exists so no redondancy
83                         Backup b_rightConv = new Backup(rankOfBackTask);
84                         addBackupTask(b_rightConv, 1); // erase if exists so no redondancy
85
86                         // ------------ 2 - for backups "i - n" (to the left of i)
87                         tmp = myRank - i;
88                         if (tmp >= 0) {
89                                 rankOfBackTask = tmp % numOfTasks;
90                         } else {
91                                 rankOfBackTask = numOfTasks - (Math.abs(tmp) % numOfTasks);
92                         }
93                         // System.out.println("i : " + i + ", rankOfBackTask : " +
94                         // rankOfBackTask);
95                         Backup b_left = new Backup(rankOfBackTask);
96                         addBackupTask(b_left, 0); // erase if exists so no redondancy
97                         Backup b_leftConv = new Backup(rankOfBackTask);
98                         addBackupTask(b_leftConv, 1); // erase if exists so no redondancy
99                 }
100
101                 // ****************************** STEP 2 : get the Backup for my task
102                 // ** get an eventual Backup (if there is one) to restart on me (try 3
103                 // times)
104                 if (req == 0) {
105                         int res = -1;
106                         int j = 0;
107
108                         while (j < 3 && res == -1) {
109                                 // scan all backup Nodes to know the rank of task
110                                 // which Backup is the most recent for my tasks
111                                 lastBackupRank = getLastRemoteBackupRank(); // return -1 if no
112                                                                                                                         // Backups
113                                 lastBackupRankConv = getLastRemoteBackupRankConvg();
114                                 // Knowing the Node which has the last (most recent) Backup for
115                                 // me,
116                                 // I get this Backup in order to restart it
117                                 System.out.println("I am going to get the Backup on "
118                                                 + lastBackupRank);
119                                 System.out.println("I am going to get the Backup Conv on "
120                                                 + lastBackupRankConv);
121                                 res = restartMyTask(lastBackupRank, lastBackupRankConv);
122                                 if (res != -1) {
123                                         System.out.println("Backup successfully got and restarted");
124                                 } else {
125                                         System.out
126                                                         .println("FAILED to get or restart the Backup at try "
127                                                                         + j
128                                                                         + "... I retry to get a Backup on another Node ("
129                                                                         + (2 - j) + " times again)");
130                                 }
131                                 j++;
132                         }
133
134                         // get backups of all neighboring nodes
135                         int destRank;
136                         TaskId destTaskId;
137                         TaskId id = Register.Instance().getListeOfTasks()
138                                         .getTaskIdOfHostStub(LocalHost.Instance().getStub());
139                         int myRank = id.getRank();
140                         JaceInterface destStub;
141                         for (int i = 0; i < BackupsManager.Instance().size(); i++) {
142                                 destRank = BackupsManager.Instance().getBackupTaskAtIndex(i, 0)
143                                                 .getTaskRank();
144                                 destTaskId = Register.Instance().getListeOfTasks()
145                                                 .getTaskIdOfRank(destRank);
146                                 destStub = destTaskId.getHostStub();
147                                 new GetBackupForNewNode(destStub, myRank).start();
148                         }
149
150                 } else
151                         restartMyTask(-1, -1);
152         }
153
154         public class GetBackupForNewNode extends Thread {
155                 JaceInterface stub;
156                 int myRank;
157
158                 public GetBackupForNewNode(JaceInterface destStub, int myRank) {
159                         stub = destStub;
160                         this.myRank = myRank;
161                 }
162
163                 public void run() {
164                         try {
165
166                                 stub.getBackupForNewNode(myRank);
167                         } catch (Exception e) {
168                         }
169                 }
170         }
171
172         public synchronized void addBackupTask(Backup t, int tag) {
173
174                 // regarder si existe cette tache ds le vecteur
175                 if (tag == 0) {
176                         int isIn = existBackupTaskOfRank(t.getTaskRank(), tag);
177
178                         if (isIn == -1) { // si elle y est pas on l'isere
179                                 liste.add( t ) ;
180
181                         }
182
183                         else { // si elle y est on remplace l'ancienne
184                                 liste.set(isIn, t);
185
186                         }
187                 } else {
188                         int isIn = existBackupTaskOfRank(t.getTaskRank(), tag);
189
190                         if (isIn == -1) {
191                                 liste_Convg.add( t ) ;
192                         } else
193                                 liste_Convg.set(isIn, t);
194                 }
195         }
196
197         public int existBackupTaskOfRank(int rank, int tag) {
198                 int existe = -1;
199                 int index = 0;
200                 if (tag == 0)
201                         while ((existe == -1) && (index < liste.size())) {
202                                 if (rank == ((Backup) liste.get(index)).getTaskRank()) {
203                                         existe = index;
204                                 } else
205                                         index++;
206                         }
207                 else
208                         while ((existe == -1) && (index < liste_Convg.size())) {
209                                 if (rank == ((Backup) liste_Convg.get(index)).getTaskRank()) {
210                                         existe = index;
211                                 } else
212                                         index++;
213                         }
214                 return existe;
215         }
216
217         // returns rank of the task that has my most recent Backup
218         private int getLastRemoteBackupRank() {
219                 int rank;
220                 TaskId task;
221                 JaceInterface stub = null;
222                 int ite;
223                 int lastIte = -1;
224                 int lastBackupRank = -1;
225                 ArrayList<Integer> v;
226                 int timeStep;
227                 int lastStep = -1;
228                 boolean ack = false;
229                 int count;
230
231                 // ask for ite number of Backups of all my Backup Nodes
232                 for (int i = 0; i < liste.size(); i++) {
233                         ite = -1;
234                         timeStep = -1;
235                         rank = ((Backup) liste.get(i)).getTaskRank();
236                         task = Register.Instance().getListeOfTasks().getTaskIdOfRank(rank);
237                         if (task == null)
238                                 System.out.println("la tache " + rank
239                                                 + "n'est pas trouvee dans le registre de " + myRank);
240
241                         stub = task.getHostStub();
242                         if (stub == null) {
243                                 System.out.println("stub is null, this node is dead !!!!");
244                         } else {
245                                 count = 0;
246                                 // if node not dead, try 3 times to know
247                                 // the ite number of its Backup for me
248                                 do {
249                                         try {
250                                                 // TODO ???
251                                                 // threads or not, for the invokation ?
252                                                 count++;
253                                                 v = stub.getIterationOfBackup(myRank, 0);
254                                                 ite = ((Integer) v.get(0)).intValue();
255
256                                                 timeStep = ((Integer) v.get(1)).intValue();
257                                                 System.out.println(" data ite = " + ite + " timeStep="
258                                                                 + timeStep + " available from task " + rank);
259                                                 ack = true;
260                                         } catch (Exception e) {
261                                                 System.out.println("The Node " + task.getHostIP()
262                                                                 + " does not answer at try " + count);
263                                         }
264                                 } while ((ack == false) && (count < MAX_COUNT_NOT_ALIVE));
265                                 if (lastStep < timeStep) {
266                                         lastStep = timeStep;
267                                         lastIte = ite;
268                                         lastBackupRank = rank;
269                                 } else if (lastStep == timeStep && ite > lastIte) {
270                                         lastIte = ite;
271                                         lastBackupRank = rank;
272                                 }
273                         }
274                 }
275                 System.out.println("last backup rank =" + lastBackupRank);
276                 return lastBackupRank;
277         }
278
279         private int getLastRemoteBackupRankConvg() {
280                 int rank;
281                 TaskId task;
282                 JaceInterface stub = null;
283                 int ite;
284                 int lastIte = -1;
285                 int lastBackupRank = -1;
286                 boolean ack = false;
287                 int count;
288                 ArrayList<Integer> v;
289                 int timeStep;
290                 int lastStep = -1;
291                 // ask for ite number of Backups of all my Backup Nodes
292                 for (int i = 0; i < liste_Convg.size(); i++) {
293                         ite = -1;
294                         timeStep = -1;
295                         rank = ((Backup) liste_Convg.get(i)).getTaskRank();
296                         task = Register.Instance().getListeOfTasks().getTaskIdOfRank(rank);
297                         stub = task.getHostStub();
298                         if (stub == null) {
299                                 System.out.println("stub is null, this node is dead !!!!");
300                         } else {
301                                 count = 0;
302                                 // if node not dead, try 3 times to know
303                                 // the ite number of its Backup for me
304                                 do {
305                                         try {
306                                                 // TODO ???
307                                                 // threads or not, for the invokation ?
308                                                 count++;
309                                                 v = stub.getIterationOfBackup(myRank, 1);
310                                                 ite = ((Integer) v.get(0)).intValue();
311                                                 timeStep = ((Integer) v.get(1)).intValue();
312                                                 System.out.println(" conv ite = " + ite + " timeStep="
313                                                                 + timeStep + " available from task " + rank);
314                                                 // System.out.println("ite = " + ite +
315                                                 // " available for task " + rank);
316                                                 ack = true;
317                                         } catch (Exception e) {
318                                                 System.out.println("The Node " + task.getHostIP()
319                                                                 + " does not answer at try " + count);
320                                         }
321                                 } while ((ack == false) && (count < MAX_COUNT_NOT_ALIVE));
322                                 if (lastStep < timeStep) {
323                                         lastStep = timeStep;
324                                         lastIte = ite;
325                                         lastBackupRank = rank;
326                                 } else if (lastStep == timeStep && ite > lastIte) {
327                                         lastIte = ite;
328                                         lastBackupRank = rank;
329                                 }
330
331                         }
332                 }
333                 return lastBackupRank;
334         }
335
336         // return 0 if good (if I successfully got a Backup),
337         // return -1 elsewhere
338         private synchronized int restartMyTask(int lastBackupRank,
339                         int lastBackupRankConv) {
340                 Backup newBackup = null;
341                 Backup newBackupConvg = null;
342                 TaskId task;
343                 JaceInterface stub = null;
344
345                 // If no Backups, lastBackupRank = -1, we start the thread at beginning
346                 if (lastBackupRank == -1) {
347                         newBackup = null;
348                 } else {
349                         // get the lastBackupRank on the corresponding BackupNode
350                         task = Register.Instance().getListeOfTasks().getTaskIdOfRank(
351                                         lastBackupRank);
352                         stub = task.getHostStub();
353                         try {
354                                 newBackup = stub.getRemoteBackup(myRank, 0);
355                                 // System.out.println("got new back normale for "+myRank);
356                         } catch (Exception e) {
357                                 System.out.println("the node " + task.getHostIP()
358                                                 + " does not answer");
359                                 // exit in order to get back and get a previous Backup
360                                 // since this one which failed was the most recent
361                                 return -1;
362                         }
363                 }
364
365                 if (lastBackupRankConv == -1) {
366                         newBackupConvg = null;
367                 } else {
368                         // get the lastBackupRank on the corresponding BackupNode
369                         task = Register.Instance().getListeOfTasks().getTaskIdOfRank(
370                                         lastBackupRankConv);
371                         stub = task.getHostStub();
372                         try {
373
374                                 newBackupConvg = stub.getRemoteBackup(myRank, 1);
375                                 // System.out.println("got new back conv for "+myRank);
376                         } catch (Exception e) {
377                                 System.out.println("the node " + task.getHostIP()
378                                                 + " does not answer");
379                                 // exit in order to get back and get a previous Backup
380                                 // since this one which failed was the most recent
381                                 return -1;
382                         }
383                 }
384
385                 // in JaceSession, clean the taskObject (Task)
386                 // and the taskThread (Thread)
387                 JaceSession.Instance().init();
388                 // create 1 TaskLauncher that will (re)start the local task within a
389                 // computing thread
390                 TaskLauncher launcher = new TaskLauncher();
391                 launcher.loadOrReloadTask(newBackup, newBackupConvg);
392                 return 0;
393         }
394
395         public Backup getBackupTaskOfRank(int rank, int tag) {
396                 int is = -1;
397                 if (tag == 0) {
398                         if (liste.isEmpty()) {
399                                 return null;
400                         } else {
401                                 is = existBackupTaskOfRank(rank, tag);
402                                 if (is != -1) {
403                                         // System.out.println("chercher un backup normal");
404                                         return (Backup) liste.get(is);
405                                 } else {
406                                         System.out.println("cette tache ou ce backup existe pas");
407                                         return null;
408                                 }
409                         }
410                 } else {
411                         if (liste_Convg.isEmpty()) {
412                                 return null;
413                         } else {
414                                 is = existBackupTaskOfRank(rank, tag);
415                                 if (is != -1) {
416                                         // System.out.println("chercher un backup convg");
417                                         return (Backup) liste_Convg.get(is);
418                                 } else {
419                                         System.out.println("cette tache ou ce backup existe pas");
420                                         return null;
421                                 }
422                         }
423                 }
424         }
425
426         public synchronized Backup getBackupTaskAtIndex(int index, int tag) {
427                 if (tag == 0)
428                         if (index < liste.size()) {
429                                 return (Backup) liste.get(index);
430                         } else {
431                                 System.out.println("cette task n'existe pas");
432                                 return null;
433                         }
434                 else if (index < liste_Convg.size()) {
435                         return (Backup) liste_Convg.get(index);
436                 } else {
437                         System.out.println("cette task n'existe pas");
438                         return null;
439                 }
440         }
441 }