// Thread per il protocollo di rielezione del master
import java.net.*;
import java.io.IOException;
import java.util.Vector;
class MasterReelection extends Thread {
private DatagramSocket soc;
private Vector slaveLoadLst; // lista con il carico degli slaves
public MasterReelection() {
super("MasterReelection");
try { System.out.print("Init MasterReelection Thread ... ");
soc=new DatagramSocket(ConstantsS.queryPort+3);
slaveLoadLst=new Vector();
System.out.println("fatto.");
} catch(SocketException ex) {
System.out.println("Slave$MasterReelection: "+ex.toString());
System.exit(ConstantsS.queryPort+1);
}
catch(SecurityException ex) {
System.out.println("Slave$MasterReelection: "+ex.toString());
System.exit(ConstantsS.queryPort+1);
}
}
// controlla se lo slave deve attivare il nuovo master
private void chkLoad() {
int minLoadPos=0;
for (int i=1;i<slaveLoadLst.size();i++)
{ LoadLstElem cur=(LoadLstElem)slaveLoadLst.elementAt(i);
LoadLstElem eletto=(LoadLstElem)slaveLoadLst.elementAt(minLoadPos);
if (cur.load<eletto.load) minLoadPos=i;
}
// controlla se lo slave e' l'eletto
LoadLstElem eletto=(LoadLstElem)slaveLoadLst.elementAt(minLoadPos);
if (eletto.slave.equals(ConstantsS.slaveIP+":"+String.valueOf(ConstantsS.queryPort+2)))
{ // essendo l'eletto, attiva il nuovo master
System.out.println("Slave$MasterReelection.chkLoad: avvio InitMasterThread");
(new InitMasterThread()).start();
}
else System.out.println("Slave$MasterReelection.chkLoad: l'inizializzazione spetta a "+eletto.slave);
// lo slave deve attendere l'attivazione del master
ConstantsS.waitForNewMaster=true;
}
public void run() {
while (true)
try { byte[] inb=new byte[22];
DatagramPacket inPac=new DatagramPacket(inb,inb.length);
soc.receive(inPac);
String msg=(new String(inPac.getData())).trim();
System.out.println("Slave$MasterReelection: pacchetto da "+(inPac.getAddress()).getHostAddress()+":"+inPac.getPort()+", msg = "+msg);
if (ConstantsS.waitForNewMaster)
{ // si e' in attesa del msg da parte del nuovo master
// che indica la fine della rielezione.
if (msg.equals("nuovo master attivato"))
{ ConstantsS.waitForNewMaster=false;
slaveLoadLst.clear();
// aggiorna l'indirizzo del nuovo master
ConstantsS.masterIP=(inPac.getAddress()).getHostAddress();
ConstantsS.masterPort=inPac.getPort();
ConstantsS.reelection=false;
System.out.println("Slave$MasterReelection: indirizzo nuovo master aggiornato");
}
}
else if (msg.equals("abort"))
slaveLoadLst.clear(); // azzera la lista in caso di abort
else { LoadLstElem el=new LoadLstElem((inPac.getAddress()).getHostAddress(),inPac.getPort(),msg);
slaveLoadLst.addElement(el);
if ((ConstantsS.sv.getSlave()).length==slaveLoadLst.size())
{ // tutti gli slaves hanno rilevato la
// morte del master.
chkLoad();
}
}
} catch(IOException ex) {
System.out.println("Slave$MasterReelection: "+ex.toString());
}
}
class LoadLstElem {
public String slave; // slave_ip:porta
public int load; // carico dello slave
public LoadLstElem(String sl_ip,int sl_port,String ld) {
super();
slave=sl_ip+":"+String.valueOf(sl_port);
load=(new Integer(ld)).intValue();
}
} // fine LoadLstElem
} // fine MasterReelection