• Non ci sono risultati.

4.2 Implementazione di PAM

4.2.5 Gli overlay node

La classe che implementa l’host per la rete PAM `e la classe PamNode che imple-

menta l’interfaccia AbstractOverlayNode del simulatore. Quest’ultima sar`a usata

all’interno del file di configurazione per indicarne le implementazioni degli host da generare.

I nodi sono implementati mediante tre classi, una per ogni tipologia di host, che estendono la classe PamNode e sono il ServerPamNode, ClientPamNode e il BalancingPamNode (come mostrato in figura 4.15.

90 PAM:Implementazione

Figura 4.16: ServerPamNode.

Il servernode

Il ServerPamNode `e l’implementazione dell’host del servernode della rete PAM ed

implementa l’interfaccia AbstractOverlayNode. Il ServerPamNode ha la struttura mostrata in figura 4.16 dove:

• nodeContact : `e il contatto dell’host;

• messageHandler : `e il gestore dei messaggi dell’host;

• nt e dt : sono rispettivamente le tabelle dei vicini laterali e diagonali per ciascuna zona associato a quell’host;

• zt : sono le zone gestite dall’host;

• objects: la lista degli oggetti contenuti in ciascuna zona; • avatars: l’insieme degli avata contenuti in ciascuna zona.

Per mantenere l’insieme delle zone gestite dall’ host, `e stata usata una Hashtable

avente come chiave l’identificativo della zona, e come valore la zona stessa.

Un hashtable avente come chiave l’id della zona `e stata usata anche per man-

tenere le entit`a (avatar e oggetti) memorizzate per ciascuna zona. Per quanto

riguarda gli oggetti il valore della tabella hash `e un vettore di oggetti di tipo

4.2 Implementazione di PAM 91

gli avatar si `e scelto di utilizzare la classe PamContact che oltre a mantenere il

contatto con il clientnode che lo gestisce, contiene anche una variabile per la sua posizione.

Nella classe ServerPamNode devono essere implementati tutti i metodi che

possono essere invocati nel file scenario o durante la simulazione, tramite i quali `e

possibile far eseguire all’Host una determinata azione in un certo istante di tempo. Le azioni implementate per il ServerNode sono le seguenti:

• put: (algoritmo 15) `e contenuto nell’action file ed eseguita per inserire gli oggetti nella DHT. Questi vengono caricati dall’oracolo e passati alla PutPamOperation che viene schedulata immediatamente nel simulatore. • join:(algoritmo 16) `e contenuto nell’action file e viene invocato dal sim-

ulatore per far entrare l’host che la esegue nella rete. Viene creata una JoinPamOperation da schedulare immediatamente nel simulatore. Viene creata anche la QueryReplyPamOperation da schedulare ad un tempo in- iziale prefissato tra i parametri di conficurazione presenti nella classe statica PamConfig.

• connect:(algoritmo 17) Deve essere eseguita solo in caso di presenza del

BalancingNode, ed `e usata nell’action file per connettere un insieme di host in

modalit`a offline. L’host che invoca tale azione viene semplicemente aggiunto

alla lista dei server offline del BalancingNode.

• leave:(algoritmo 18) `e chiamata nell’action file per avviare l’uscita volon- taria di un ServerPamNode dalla rete. Viene creata la LeavePamOperation

e schedulata immediatamente. Tale operazione pu`o essere eseguita solo in

una fase in cui l’overlay `e statica.

• joinOfflineNode(algoritmo 19): `e chiamata dal ServerNode offline in se- guito ad un operazione di bilanciamento. Viene creata la JoinPamOperation da schedulare immediatamente e l’operazione QueryReplyPamOperation al

tempo specificato in scheduleTime, che `e stato calcolato in maniera da sin-

cronizzare l’operazione di query nel simulatore. Viene specificata anche

l’iterazione usata per il controllo della correttezza dei risultati delle query inviate con quelli calcolati dall’oracolo.

92 PAM:Implementazione Algorithm 15: put input : begin 1 objectList = getAllOracleObjects(); 2

putOperation = createP utOperation(host, objectList);

3 putOperation.scheduleImmediately(); 4 end 5 Algorithm 16: join

input : scheduleT ime begin

1

joinOperation = createJ oinOperation(host);

2

joinOperation.scheduleImmediately();

3

queryReplyOperation = createQueryReplyOperation(host);

4

queryReplyOperation.scheduleAtT ime(P amConf ig.start + P amConf ig.delay);

5

end

6

• splitOverloadedZone:(algoritmo 20) `e invocata dal ServerNode meno cari-

co che invier`a una JoinPamMessage al server pi`u carico che gestisce la zona

avente il zoneId specificato. Il zoneId `e l’id della zona pi`u carica del server

che la gestisce.

I primi quattro metodi rappresentano azioni che vengono chiamate nel file scenario (o action file), mentre le ultime due sono usate dall’algoritmo di bilanci- amento per eseguire la split di un zona per dividere il carico in esso presente. Per i meccanismi di bilanciamento si riusa l’algoritmo di Join di CAN in quanto per- mette di dividere la zona in due e di affidarne una parte al server che ha richiesto tale operazione.

4.2 Implementazione di PAM 93

Algorithm 17: connect

input : begin

1

balancingN ode = bootstrap.getBalancingN ode();

2

balancingN ode.addInOf f line(host);

3 end 4 Algorithm 18: leave input : begin 1 leaveOperation = createLeaveOperation(host); 2 leaveOperation.scheduleImmediately(); 3 end 4 Algorithm 19: joinOfflineNode

input : scheduleT ime, iteration begin

1

joinOperation = createJ oinOperation(host);

2

joinOperation.scheduleImmediately();

3

queryReplyOperation = createQueryReplyOperation(host, iteration + 1);

4

queryReplyOperation.scheduleAtT ime(scheduleT ime);

5

end

6

Algorithm 20: splitOverloadedZone

input : overloadedContact, overloadedZoneId begin

1

position = myContact.getP osition

2

msg = J oinM essagemyContact, overloadedZoneId, position; send msg to overloadedContact;

3

end

94 PAM:Implementazione

Figura 4.17: Modellazione del vicino di una zona.

Tabella di routing La tabella di routing del ServerPamNode `e composta da

due tabelle hash aventi come chiave l’identificativo della zona e come valore la lista oggetti di tipo Neighbour. Le due tabelle hash mantengono rispettivamente la lista dei vicini laterali e diagonali di ciascuna zona gestita dal nodo. La figura 4.17 mostra la struttura della classe Neighbour che contiene:

• zone: la zona vicina che `e definito nella classe Zone che possiede l’iden-

tificativo della zona (zoneId ), le coordinate della zona ([x1, x2][y1, y2]), la

direzione in cui `e stata divisa la zona (splitDirection) e il vid ;

• dir : la direzione in cui `e posizionata la zona vicina; • serverContact : il contatto del server che gestisce la zona.

Nella classe sono stati previsti metodi per verificare la vicininza di zone e

l’appartentenza di punti in una zona. Inoltre `e stata implementata l’operazione

di split e di merge di una zona che vengono chiamate rispettivamente durante la fase di join e di leave di un host.

La direzione di una zona indica la posizione della zona vicina ed `e rappresentata

da un numero intero da 0 a 7 che rappresentano ciascuna delle possibili direzioni (Est, Sud, Ovest, Nord, NordEst, SudEst, SudOvest, NordOvest).

Infine la classe Neighbour prevede un metodo clone da utilizzare ogni qual volta sia necessario inviare un vicino ad un host della rete.

Gestore dei messaggi Il gestore dei messaggi `e la parte pi`u importante del

4.2 Implementazione di PAM 95

Figura 4.18: Modellazione del gestore dei messaggi.

classe implementa la classe TransMessageListener usata per ricevere le notifiche di un arrivo di un messaggio.

Come mostrato in figura 4.18 deve contenere il riferimento al ServerPamNode a cui corrisponde e il metodo messageArrived in cui gestire i messaggi. Esso contiene come parametro la classe TransMsgEvent usata per recuperare il paylode del messaggio.

Verr`a ora descritta la gestione di ciascun messaggio ricevuto dal ServerPamNode.

Il JoinPamMessage viene gestito nell’algoritmo 21 che controlla se la zona avente il zoneId contiene la posizione del nodo che ha richiesto la join (joiningN ode). Se vale tale condizione allora la zona viene divisa aggiornando la tabella di routing

e le entit`a presenti delle due zone risultanti. Inoltre viene inviato al joiningN ode

un messaggio di tipo AddZoneP amM essage contenente la nuova zona e tutte le informazioni ad essa correlate. Se la zona non contiene position il JoinPamMes-

sage viene inoltrato verso il nodo avente la zona pi`u vicina a position. Il metodo

getComponent() restituisce l’host destinatario che gestisce il messaggio.

L’AddZonePamMessage viene gestito dall’algoritmo 22. Questo messaggio viene inviato as esempio, quando un servernode cede una zona ad un altro, o in

fase di join o in fase di bilanciamento. L’algoritmo controlla se il messaggio `e

stato inviato in seguito ad un’operazione di join, o a causa di operazione di leave. Se il messaggio proviene da un messaggio di leave occorre controllare se il nodo destinatario possiede delle zone che possono essere fuse con quella ricevuta. In caso di join, viene aggiunto al nodo destinatario la zona con la sua tabella di

routing e con le sue entit`a. Inoltre il nodo deve inviare un messaggio di tipo

RegistrationPamMessage a tutti gli avatar a cui notificare la zona e il server a cui appartengono. Se il nodo che entra nella rete era inizialmente offline, lo si

96 PAM:Implementazione

Algorithm 21: processJoinPamMessage

input : msg begin

1

(joiningN ode, zoneId) = msg.getF romM sg();

2

position = joiningN ode.getP osition();

3 mynode = getComponent(); 4 myzone = mynode.getZone(zoneId); 5 if myzone.contains(position) then 6 newzone = splitzone(myzone); 7 (nt, dt) = updateRoutingT able(zoneId); 8

(avts, objs) = updateEntities(zoneId);

9

msg = createAddN ewZoneM sg(newzone, nt, dt, objs, avts);

10

send msg to joiningN ode;

11 end 12 else 13 (nt, dt) = mynode.getZoneRoutingT able(zoneId); 14

n = f indT heN earestN eighbour(position, nt, dt);

15

msg = J oinM essage(joiningN ode, n.getZone(), position);

16 send msg to n; 17 end 18 end 19

4.2 Implementazione di PAM 97

Algorithm 22: processAddZoneMessage

input : msg begin

1

(newzone, nt, dt, avts, objs) = msg.getF romM sg();

2

node = getComponent();

3

if msg.isF romLeaveOperation() then

4

zt = node.getAllM yZone();

5

(zone, nt, dt) = merging(zt, newzone, nt, dt, avts, objs);

6

sendU pdateN eighbourM essage(nt, dt, zone);

7 end 8 else 9 node.addZone(newzone); 10

node.addRoutingT able(nt, dt, newzone.getZoneId());

11

node.addEntities(objs, avts, newzone.getZoneId());

12

for each avt ∈ avatars do

13

send RegistrationM essage(node.getContact(), newzone.getZoneId()) to

14

avt; end

15

if node.isOf f line() then

16 bootstrap.register(node); 17 balancingN ode.setOnline(node); 18 end 19 end 20 end 21

aggiunge al nodo di bootstrap e si sposta nei contatti online del balancing node.

Il RangeQueryPamMessage `e gestito dall’algoritmo 23. Questo messaggio

viene ricevuto da un server perch`e inviato da un server vicino per la risoluzione

di una range query che non pu`o essere completamente risolta da lui.

I metodi f indObjects e f indAvatars risolvono rispettivamente la query per calcolare una parte della vista dell’AoI. La vista da calcolare corrisponde alle en-

tit`a presenti nella zona indicata dal zoneId e nell’AoI, avente come centro position.

I risultati della query vengono poi inviati all’avatar interessato attraverso un QueryReplyP amM essage.

Il MovePamMessage `e gestito dall’algoritmo 24. Il messaggio `e inviato dal

98 PAM:Implementazione

Algorithm 23: processRangeQueryPamMessage

input : msg begin

1

(avatar, position, zoneId) = msg.getF romM sg();

2

node = getComponent();

3

objs = node.f indObjects(position, zoneId);

4

avts = node.f indAvatars(position, zoneId);

5

msg = createQueryReplyP amM essage(objs, avts);

6

send msg to avatar;

7

end

8

semplicemente la posizione, altrimenti controlla se `e contenuto in una zona gestita

dallo stesso ServerNode. Se esiste tale zona, il server lo sposta in questa e invia un RegistrationPamMessage all’avatar per notificare il cambiamento di zona. In caso contrario si possono verificare due casi in base alla distanza percorsa dall’avatar.

Se l’avatar effettua piccoli spostamenti `e sufficiente controllare se esiste una zona

vicina che lo contenga ed inviargli un messaggio di tipo AddAvatarPamMessage. Se invece l’avatar effettua grandi spostamenti, come per esempio un teletrasporto da una zona all’altra, occorre riapplicare il routing per cercare la zona proprietaria. Il metodo f indN ewServerZone cerca se esiste un vicino che contenga la posizione dell’avatar e restituisce null se non esiste.

Il FindPamMessage `e gestito dall’algoritmo 25. Quando un ServerPamNode

riceve questo tipo di messaggio deve controllare se l’avatar `e posizionato all’interno

delle zone da esso possedute. In tal caso aggiunge il contatto dell’avatar con la sua nuova posizione per zoneId, e cominica il cambiamento di server e di zona all’avatar attraverso un RegistrationPamMessage. In caso contrario riapplica l’algoritmo di

routing inoltrando il FindPamMessage verso il Neighbour pi`u vicino a position.

L’AddAvatarPamMessage `e gestito dall’algoritmo 26. Quando un servern-

ode riceve questo messaggio deve aggiungere tra le sue entit`a l’avatar che si `e

spostato nella sua zona. La zona in cui l’avatar si `e spostato `e specificato nel

zoneId contenuto nel messaggio. Infine invia un messaggio di registrazione al client proprietario dell’avatar per notificargli il cambiamento di server e di zona.

L’UpdateNeighbourPamMessage `e gestito dall’algoritmo 27 e si occupa di

4.2 Implementazione di PAM 99

Algorithm 24: processMovePamMessage

input : msg begin

1

(avatar, position, zoneId) = msg.getF romM sg();

2 node = getComponent(); 3 zone = node.getZone(zoneId); 4 if zone.contains(position) then 5

node.updateAvatarP osition(avatar, position, zoneId);

6

end

7

else

8

node.removeAvatarP osition(avatarnode, zoneId);

9

for each z ∈ node.getZoneT able() \ zone do

10

if z.contains(position) then

11

node.addAvatarP osition(avatar, position, z.getZoneId());

12

msg =

13

createRegistrationM sg(node.getContact(), newzone.getZoneId()); send msg to avatar; f ound = true; 14 end 15 end 16

if f ound == true then

17

(newserver, newzoneId) =

18

f indN ewServerZone(node.getAllRoutingT able, position); if newserver == null then

19

(nt, dt) = mynode.getAllRoutingT able();

20

n = getT heN earestN eighbour(position, nt, dt);

21

msg = createF indM essage(avatar, position, n.getZoneId());

22 send msg to n; 23 end 24 else 25

msg = createAddAvatarM essage(avatar, position, newzoneId);

26 send msg to newserver; 27 end 28 end 29 end 30 end 31

100 PAM:Implementazione

Algorithm 25: processFindPamMessage

input : msg begin

1

(avatar, position) = msg.getF romM sg();

2 node = getComponent(); 3 zt = node.getZoneT able(); 4 if ∃z ∈ zt : z.contains(position) then 5

node.addAvatar(avatar, position, z.getZoneId());

6

msg = sendRegistrationM essage(node.getContact(), z.getZoneId());

7 send msg to avatar; 8 end 9 else 10 (nt, dt) = mynode.getAllRoutingT able(); 11

n = getT heN earestN eighbour(position, nt, dt);

12

msg = createF indM essage(avatar, position, n.getZoneId());

13 send msg to n; 14 end 15 end 16 Algorithm 26: processAddAvatarPamMessage input : msg begin 1

(avatar, position, zoneId) = msg.getF romM sg();

2

node = getComponent();

3

node.addZoneAvatar(avatar, position, zoneId);

4

msg = sendRegistrationM essage(node.getContact(), zoneId);

5

send msg to avatar;

6

end

4.2 Implementazione di PAM 101

Algorithm 27: processUpdateNeighbourMessage

input : msg begin

1

(neighbour, zoneId) = msg.getF romM sg();

2

node = getComponent();

3

node.updateN eighbour(neighbour, zoneId);

4

end

5

particolare la funzione updateNeighbour si occupa di aggiornare il vicino presente nella tabella di routing di zoneId, sostituendo la vecchio vicino con il nuovo.

L’AddNeighbourPamMessage `e gestito dall’algoritmo 28 e si occupa di

aggiungere il vicino laterale nella rispettiva tabella di routing di zoneId. Il metodo addNeighbour aggiunge un Neighbour alla HashTable dei vicini laterali di zoneId.

L’RemoveNeighbourPamMessage `e gestito dall’algoritmo 29 e si occupa di

rimuovere il vicino laterale dalla rispettiva tabella di routing di zoneId. Il metodo removeNeighbour rimuove il Neighbour dalla HashTable dei i vicini laterali avente come chiave zoneId.

L’AddNeighbourPamMessage `e gestito dall’algoritmo 30 e si occupa di

aggiungere il vicino diagonale nella rispettiva tabella di routing di zoneId. Il metodo addDiagonal aggiunge un Neighbour alla HashTable dei vicini diagonali di zoneId.

L’RemoveNeighbourPamMessage `e gestito dall’algoritmo 31 e si occupa

di rimuovere il vicino diagonale dalla rispettiva tabella di routing di zoneId. Il metodo removeDiagonal rimuove il Neighbour dalla HashTable dei vicini diagonali avente come chiave zoneId.

102 PAM:Implementazione

Algorithm 28: processAddNeighbourMessage

input : msg begin

1

(neighbour, zoneId) = msg.getF romM sg();

2

node = getComponent();

3

node.addN eighbour(neighbour, zoneId);

4 end 5 Algorithm 29: processRemoveNeighbourPamMessage input : msg begin 1

(neighbour, zoneId) = msg.getF romM sg();

2

node = getComponent();

3

node.removeN eighbour(neighbour, zoneId);

4 end 5 Algorithm 30: processAddDiagonalPamMessage input : msg begin 1

(neighbour, zoneId) = msg.getF romM sg();

2 node = getComponent(); 3 node.addDiagonal(neighbour, zoneId); 4 end 5 Algorithm 31: processRemoveDiagonalPamMessage input : msg begin 1

(neighbour, zoneId) = msg.getF romM sg();

2 node = getComponent(); 3 node.removeDiagonal(neighbour, zoneId); 4 end 5

4.2 Implementazione di PAM 103

Figura 4.19: ClientPamNode.

Il clientnode

Il ClientPamNode `e la classe che implementa l’host del clientnode di PAM ed es-

tende la classe P amN ode. Il ClientPamNode rappresenta l’applicazione attraverso

la quale il giocatore si connette alla rete, la cui struttura `e mostrata in figura 4.19

ed `e la seguente:

• nodeContact : il contatto dell’host;

• messageHandler : il gestore dei messaggi del nodo;

• iteration: usato per mantenere l’iterazione in cui l’avatar si trova;

• view : entit`a presenti nell’AoI per l’iterazione specificata in iteration;

• server : il contatto del server a cui l’avatar `e registrato; • zoneId : la zona in cui l’avatar `e posizionato.

Il ClientPamNode possiede un’unica azione che pu`o essere chiamata dal file

scenario. Tale azione `e la seguente

• connect:(algoritmo 32) controlla se il clientnode che ha eseguito tale azione `

e gi`a connesso alla rete. Se il clientnode non `e connesso alla rete e esiste

almeno un servernode nella rete, allora crea una RegisterClientPamOper-

ation da schedulare immediatamente che si occuper`a di registrarlo pres-

so il servernode corretto. La RegisterClientPamOperation deve conoscere almeno il contatto di un servernode per poter avviare il procedimento di registrazione.

104 PAM:Implementazione

Algorithm 32: connect

begin

node = getComponent();

bootstrap = getBootstrapN ode(); if node.isOf f line() then

if bootstrap.hasServer() then

serverContact = bootstrap.getServerContact();

regOp = createRegisterClientP amOperation(node, serverContact); regOp.scheduleImmediately();

end end end

Gestore dei messaggi Il gestore dei messaggi del ClientPamNode serve a ge-

stire tutti messaggi provenienti dai servernode. Essa implementa la classe Trans- MessageListener del simulatore con cui ricevere le notifiche quando arriva un mes- saggio. I messaggi ricevuti dal clientnode possono essere di due tipi, un messaggio di tipo RangeQueryReplyPamMessage e uno di tipo RegistrationPamMessage. Per

ognuno di essi verr`a ora illustrata la gestione.

Il RangeQueryReplyPamMessage `e gestito dall’algoritmo 33. Esso di oc-

cupa di memorizzare le entit`a contenute nel messaggio nella propria vista e con cui

il giocatore potr`a interagire. Per ogni iterazione il ClientNode potr`a ricevere pi`u

messaggi di tipo RangeQueryReplyPamMessage provenienti da diversi servernode

ognuno dei quali conterr`a una porzione della vista. La porzione di vista ricevuta

`e quella relativa alla zona che interseca l’AoI del giocatore. Come visto nel capi-

tolo 3 un’AoI pu`o intersecare pi`u zone, ci`o implica la risoluzione della query per

ognuna di queste. Ogni zona intersecata pu`o essere gestita da un diverso server

che deve risolvere la query e inviare i risultati all’avatar. Ogni messaggio di tipo

RangeQueryReplyPamMessage conterr`a anche l’iterazione a cui corrisponde. Se

l’iterazione cambia allora la vista dell’avatar viene azzerata per far spazio alla vista per nuova iterazione.

Il RegistrationPamMessage `e gestito dall’algoritmo 34 Esso si occupa di

registrare nel clientnode il contatto del servernode a cui `e ora registrato e il zoneId

4.2 Implementazione di PAM 105

Algorithm 33: processRangeQueryReplyMessage

input : msg begin

1

(objects, avatars, iteration) = msg.getF romM sg();

2

currentIteration = getCurrentIteration();

3

node = getComponent();

4

if iteration > currentIteration then

5 currentIteration = iteration; 6 node.clearV iew(); 7 end 8

node.addV iewEntities(objects, avatars);

9 end 10 Algorithm 34: processRegistrationMessage input : msg begin 1

(serverContact, zoneId) = msg.getF romM sg();

2 node = getComponent(); 3 node.setServerN ode(serverContact); 4 node.setZoneId(zoneId); 5 end 6

106 PAM:Implementazione

Figura 4.20: BalancingPamNode.

Il balancingnode

Il BalancingPamNode `e la classe implementata per l’host che svolger`a le fun-

zionalit`a del balancingnode ed estende la classe PamConfig. Il balancingnode `e

un’unit`a centralizzata che mantiene tutti i riferimenti con i servernode presenti

nell’overlay ai fini di monitorare il carico della rete, riorganizzando la sua struttura per bilanciarla. La figura 4.20 mostra la struttura della classe BalancingPamNode che dipende dall’algoritmo usato. In base all’algoritmo di bilanciamento illustrato nel capitolo 3 il BalancingPamNode contiene:

• offlineServer : la lista dei servernode in attesa di entrare nella rete; • onlineServer : la lista dei servernode presenti nella rete.

Il BalancingPamNode possiede un unica operazione da chiamare dal file sce-

nario che `e la seguente:

• connect:(algoritmo 35) registra il balancingnode al nodo di bootstrap e crea l’operazione di tipo BalancingPamOperation per l’iterazione 0 da schedulare

all’istante di tempo t0+ 2t, dove t0 `e restituito dalla varibile start e t dalla

variabile delay dell classe di configurazione P amConf ig.

deve essere inizializzato prima di qualsiasi altro nodo presente nell’overlay

attraverso l’azione connect, il cui funzionamento `e mostrato nell’algoritmo 35.

L’azione connect per il balancingnode deve essere eseguita nel file scenario prima di qualsiasi altra azione nella rete.

Documenti correlati