Rielezione di un nuovo master
La rielezione consente alla rete di far fronte a una caduta del nodo master avviando un nuovo processo master
su un nodo slave e ripristinando lo stato che il master aveva prima della caduta. Per fare cio' occorre selezionare
uno slave tra quelli della rete locale a cui affidare il compito del riavviamento del nuovo master. Il criterio
di selezione di tale slave si basa sul carico, cioe' sul numero di thread attivi su ogni slave (mantenuto nella variabile
ConstantsS.slaveLoad): viene scelto lo slave con il carico minore e, in
caso di parita' di carico, quello che si e' accorto della caduta del master per primo.
Come protocollo di trasmissione e' stato scelto UDP per la maggiore efficienza rispetto a quella offerta da TCP,
rinunciando, pero', all'affidabilita'. Per questo motivo e per semplificare le cose si e' ipotizzato che in fase di rielezione
non possano verificarsi dei malfunzionamenti.
Lo thread responsabile del mantenimento della tabella dei carichi degli slave della rete e' MasterReelection.
Questo processo rimane in attesa su una porta UDP di pacchetti provenienti dagli altri slave della rete, contenenti il carico del
mittente. Ricevuto un pacchetto di questo tipo, lo slave mittente (identificato da ip:porta) e il suo carico vengono inseriti
nella lista dei carichi, che e' realizzata mediante un Vector i cui elementi sono oggetti LoadLstElem.
Il numero massimo di pacchetti attesi e' pari al numero degli slave vivi della rete (determinato mediante l'oggetto SlaveVivi)
e tale numero deve rimanere costante durante la rielezione (ecco perche' la registrazione di nuovi slave non e' consentita
in questa fase). Prima che la lista sia piena lo thread considera anche messaggi di "abort" provenienti da slave che sono riusciti
a contattare il master: in questo caso la lista dei carichi viene svuotata e si esce dalla fase di rielezione.
Una volta che la lista e' piena, cioe' tutti gli slave della rete hanno rilevato la caduta del master, viene estratto da essa lo slave con
il carico minore (in caso di parita' di carico viene estratto il primo che ha rilevato la morte del master):
- se tale slave e' differente dallo slave del nodo locale si attende che "l'eletto" attivi il nuovo master;
- se, invece, lo slave estratto e' quello del nodo locale viene attivato lo thread InitMasterThread
che ha il compito di avviare il processo del nuovo master.
In ogni caso MasterReelection rimane in attesa dell'avviamento del nuovo master e del messaggio "nuovo master attivato"
proveniente da quest'ultimo che indica la fine della rielezione (si veda anche l'avviamento del master).
Durante questa attesa (fase determinata dal valore della variabile ConstantsS.waitForNewMaster) non vengono
considerati eventuali messaggi di "abort": il vecchio master e' ormai considerato spacciato.
Una volta terminata la rielezione la lista dei carichi viene svuotata e si ritorna al funzionamento normale.