Differences between revisions 2 and 3
Revision 2 as of 2015-08-15 17:05:29
Size: 8881
Editor: lukisi
Comment:
Revision 3 as of 2015-08-25 11:45:51
Size: 15169
Editor: lukisi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 21: Line 21:
Il metodo ha come argomento lo stub per contattare il vicino. Prevede l'eccezione !StubNotWorkingError.

Restituisce una istanza di ICoordinatorNeighborMap.
Line 22: Line 26:
Il modulo permette di chiedere ad un vicino del nodo di prenotare per lui un posto nel suo g-nodo di livello ''l'' con il metodo ''ask_reservation'' di !CoordinatorManager. Il modulo permette di chiedere ad un vicino del nodo di prenotare per lui un posto nel suo g-nodo di livello ''l'' con il metodo ''get_reservation'' di !CoordinatorManager.

Il metodo ha come argomento lo stub per contattare il vicino e il livello a cui fare richiesta. Prevede l'eccezione !StubNotWorkingError e l'eccezione !SaturatedGnodeError.

Restituisce una istanza di ICoordinatorReservation.

== Comunicazioni tra vicini ==
Quando il modulo vuole chiedere ad un vicino informazioni sui posti liberi nei suoi g-nodi usa il metodo remoto ''retrieve_neighbor_map''. Non ha argomenti. Non prevede eccezioni, oltre alle solite !StubError e !DeserializeError. Restituisce una istanza di ICoordinatorNeighborMap.

L'interfaccia ICoordinatorNeighborMap è esposta dal modulo. La classe che viene istanziata è !NeighborMap, una classe serializzabile interna al modulo.

----
Quando il modulo vuole chiedere ad un vicino di prenotare per lui un posto nel suo g-nodo di livello ''l'' usa il metodo remoto ''ask_reservation''. Ha come argomento il livello ''l''. Prevede l'eccezione !SaturatedGnodeError, oltre alle solite !StubError e !DeserializeError. Restituisce una istanza di ICoordinatorReservation.

L'interfaccia ICoordinatorReservation è esposta dal modulo. La classe che viene istanziata è Reservation, una classe serializzabile interna al modulo.
Line 31: Line 49:
 * ''bookings''. Lista di liste di Booking. Memoria delle prenotazioni. L'elemento ''i''-esimo è la lista di prenotazioni attive per il nostro g-nodo di livello ''i''+1. La classe Booking ha una posizione (int ''pos'') e un time-to-live (Timer ''ttl'').
 * ''max_eldership''. Lista di int. L'elemento ''i''-esimo dice il valore più alto di progressione già assegnato ad una prenotazione per un nuovo g-nodo di livello ''i'' dentro il nostro g-nodo di livello ''i''+1. Un valore più alto significa che il g-nodo è arrivato dopo, cioè esso è più giovane.
 * ''bookings''. Lista di liste di Booking. Memoria delle prenotazioni. Contiene ''levels'' elementi. L'elemento ''i''-esimo è la lista di prenotazioni attive per il nostro g-nodo di livello ''i''+1. La classe Booking ha una posizione (int ''pos'') e un time-to-live (Timer ''ttl''). E' una classe serializzabile e interna al modulo.
 * ''max_eldership''. Lista di int. Contiene ''levels'' elementi. L'elemento ''i''-esimo dice il valore più alto di progressione già assegnato ad una prenotazione per un nuovo g-nodo di livello ''i'' dentro il nostro g-nodo di livello ''i''+1. Un valore più alto significa che il g-nodo è arrivato dopo, cioè esso è più giovane.
Line 35: Line 53:
 * In una nuova tasklet:
  * Avvia le operazioni di recupero dei record di sua pertinenza con i metodi ''!PeersManager.begin_retrieve_cache'' e ''!PeersManager.next_retrieve_cache''.
  . Trattandosi di un servizio non opzionale, non attende l'evento ''!PeersManager.participant_maps_ready''.
  . E' compito della classe !CoordinatorService costruire la richiesta ''r'' di "recupero records".
  * Ad ogni chiamata che restituisce ''True'' va interpretata la risposta ''resp'' e vanno memorizzati i records di pertinenza. '''TODO''' spiegare cosa va indicato nella richiesta e quali membri vanno memorizzati sulla base della risposta.
  * Al termine imposta il suo flag ''retrieve_cache_done''.
 * Riceve come argomento ''lvl'' il livello del g-nodo appena costituito dal nostro nodo.
 * Se ''lvl'' = ''levels'':
  * Imposta il suo flag ''retrieve_cache_done''.
 * Altrimenti:
  * In una nuova tasklet:
   * Avvia le operazioni di recupero dei record di sua pertinenza. Trattandosi di un servizio non opzionale, non attende l'evento ''!PeersManager.participant_maps_ready''.
   * Costruisce la richiesta ''r'' di tipo "retrieve_cache" dal livello ''lvl''+1 in su.
   * Avvia il primo recupero con il metodo ''!PeersManager.begin_retrieve_cache''
   . Attende l'esito, cioè il booleano restituito, la risposta ''resp'' da interpretare, l'oggetto IPeersContinuation ''cont'' da passare nelle chiamate successive.
   * Se ''resp'' ≠ ''null'':
    * Si accerta che ''resp.bookings.size'' = ''resp.max_eldership.size'' = ''levels - lvl''. Altrimenti emette un warning e ignora questa risposta.
    * Per ''i'' da 0 a ''resp.bookings.size-1'':
     * ''j'' = ''lvl + i''.
     * Per ogni Booking ''b'' ∈ ''resp.bookings[i]'':
      * Se ''b'' ∉ ''bookings[j]'':
       * Aggiungi ''b'' a ''bookings[j]''.
     * Se ''resp.max_eldership[i]'' > ''max_eldership[j]'':
      * ''max_eldership[j]'' = ''resp.max_eldership[i]''.
   * Se l'esito è ''True'':
    * While True:
     * Avvia un altro recupero con il metodo ''!PeersManager.next_retrieve_cache'' passando la IPeersContinuation ''cont''.
     . Attende l'esito, cioè il booleano restituito e la risposta ''resp'' da interpretare.
     * Se ''resp'' ≠ ''null'':
      * In base a ''resp'' modifica i propri membri ''bookings'' e ''max_eldership'', come sopra.
     * Se l'esito è ''False'':
      * Esci dal ciclo.
   * Al termine imposta il suo flag ''retrieve_cache_done''.
Line 51: Line 90:
 * Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione !DeserializeError.  * Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione !DeserializeError. Inclusi errori nei valori accettabili di ''lvl''.
Line 53: Line 92:
 * Verifica che un posto libero esiste nel mio g-nodo di livello ''lvl''. Altrimenti lancia una eccezione.
 * Scegli un posto ''pos''.
 * Segnala il posto come prenotato nella memoria.
 * Verifica nella mappa ''map'' del !CoordinatorManager quali posizioni sono libere nel livello ''lvl''. Se nessuna posizione risulta libera, lancia una eccezione.
 * Dalla lista ottenuta di posizioni libere, esclude quelle presenti nelle prenotazioni ''bookings(lvl-1)'' del !CoordinatorService. Nello scorrere questa lista, rimuove le istanze di Booking che sono scadute (membro ''ttl''). Se nessuna posizione risulta libera, lancia una eccezione.
 * Scegli una posizione ''pos''.
 * Segnala la prenotazione nella memoria. Cioè crea una istanza di Booking ''pos'' con ''ttl'' a 20 secondi (una {{{private const}}} nel codice) nella lista ''bookings(lvl-1)'' del !CoordinatorService.
Line 59: Line 99:
 * Avvia la prima replica con il metodo ''!PeersManager.begin_replica''. Come ''q'' mettiamo 15 (una {{{private const}}} nel codice). Come perfect_tuple il valore ottenuto con il metodo ''perfect_tuple'' della classe !CoordinatorClient. E' compito della classe !CoordinatorService costruire la richiesta ''r'' di "replica prenotazione su ''pos''".  * Avvia la prima replica con il metodo ''!PeersManager.begin_replica''. Questi sono gli argomenti:
  
. Come ''q'' mettiamo 15 (una {{{private const}}} nel codice).
  .
Come perfect_tuple il valore ottenuto con il metodo ''perfect_tuple'' della classe !CoordinatorClient con la chiave ''lvl''.
  .
Costruisce la richiesta ''r'' di tipo 'replica_reserve' per la posizione ''pos'' con anzianità ''eldership'' dentro il nostro g-nodo di livello ''lvl''.
Line 61: Line 104:
 . La risposta ''resp'' dovrebbe essere semplicemente OK. Il booleano restituito è ''False'' solo se si è avuta l'eccezione !NoParticipantsInNetwork.  . Il booleano restituito è ''False'' solo se si è avuta l'eccezione !NoParticipantsInNetwork. In questo caso si ignora la risposta ''resp''.
 . La risposta ''resp'' dovrebbe essere semplicemente OK, cioè una istanza di !CoordinatorReplicaReserveResponse con i membri a ''null''. Altrimenti va prodotto un warning descrittivo da usare nella fase di debug del modulo; quando il modulo è stabile questa situazione va semplicemente ignorata.
Line 63: Line 107:
  * Avvia la seconda replica con il metodo ''!PeersManager.next_replica'' passando la IPeersContinuation.   * Avvia la seconda replica con il metodo ''!PeersManager.next_replica'' passando la IPeersContinuation ''cont''.
Line 65: Line 109:
  . La risposta ''resp'' dovrebbe essere semplicemente OK. Il booleano restituito è ''False'' solo se si è avuta l'eccezione !NoParticipantsInNetwork.   . Il booleano restituito è ''False'' solo se si è avuta l'eccezione !NoParticipantsInNetwork. In questo caso si ignora la risposta ''resp''.
  . La risposta ''resp'' dovrebbe essere semplicemente OK. Altrimenti va prodotto un warning descrittivo.
Line 69: Line 114:
     * Avvia una replica con il metodo ''!PeersManager.next_replica'' passando la IPeersContinuation.      * Avvia una replica con il metodo ''!PeersManager.next_replica'' passando la IPeersContinuation ''cont''.
Line 71: Line 116:
     . La risposta ''resp'' dovrebbe essere semplicemente OK. Il booleano restituito è ''False'' se abbiamo completato ''q'' repliche o se si è avuta l'eccezione !NoParticipantsInNetwork.      . Il booleano restituito è ''False'' se abbiamo completato ''q'' repliche o se si è avuta l'eccezione !NoParticipantsInNetwork. In questo caso si ignora la risposta ''resp''.
     . La risposta ''resp'' dovrebbe essere semplicemente OK. Altrimenti va prodotto un warning descrittivo.
Line 75: Line 121:
 * Restituisce ret.  * Restituisce ''ret''.

==== Metodo replica_reserve ====
Se il metodo ''exec'' della classe !CoordinatorService viene chiamato con una istanza di !CoordinatorRequest (si veda sotto) che ha il membro ''name'' = 'replica_reserve' allora abbiamo ricevuto una richiesta di "replica per una prenotazione del posto ''pos'' con anzianità ''eldership'' nel nostro g-nodo di livello ''lvl''". Le operazioni da fare sono:
 * Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione !DeserializeError. Inclusi errori nei valori accettabili di ''lvl'' e ''pos''.
 * Atomic on.
 * Segnala la prenotazione nella memoria. Cioè crea una istanza di Booking ''pos'' nella lista ''bookings(lvl-1)'' del !CoordinatorService.
 * Se ''max_eldership(lvl-1)'' < ''eldership'':
  * Imposta ''max_eldership(lvl-1)'' = ''eldership''.
 * Atomic off.
 * Restituisce OK.

==== Metodo retrieve_cache ====
Se il metodo ''exec'' della classe !CoordinatorService viene chiamato con una istanza di !CoordinatorRequest (si veda sotto) che ha il membro ''name'' = 'retrieve_cache' allora abbiamo ricevuto una richiesta di "recupera i record delle prenotazioni dal livello ''lvl'' in su", con 0 < ''lvl'' ≤ ''levels''. Le operazioni da fare sono:
 * Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione !DeserializeError. Inclusi errori nei valori accettabili di ''lvl''.
 * Prepara ''ret'' con gli elementi da ''lvl''-1 in su della lista ''bookings'' di !CoordinatorService e con gli elementi da ''lvl''-1 in su della lista ''max_eldership'' di !CoordinatorService.
 * Restituisce ''ret''.
Line 85: Line 147:
 * ''lvl''. Usato se ''name'' = 'reserve'. Un intero che indica il livello in cui riservare un posto.  * ''reserve_lvl''. Usato se ''name'' = 'reserve'. Un intero che indica il livello del g-nodo dentro il quale riservare un posto.
 * ''cache_from_lvl''. Usato se ''name'' = 'retrieve_cache'. Un intero che dice di passare i record da quel livello in su.
 * ''replica_lvl''. Usato se ''name'' = 'replica_reserve'. Un intero che dice il livello del g-nodo dentro il quale è stato prenotato un posto.
 * ''replica_pos''. Usato se ''name'' = 'replica_reserve'. Un intero che dice la posizione della prenotazione.
 * ''replica_eldership''. Usato se ''name'' = 'replica_reserve'. Un intero che dice l'anzianità del posto prenotato.
Line 96: Line 162:
Viene definita la classe interna !CoordinatorReplicaReserveResponse. Si tratta di una classe serializzabile che implementa l'interfaccia segnaposto (vuota) IPeersResponse. Serve come risposta solo per la richiesta 'replica_reserve'. Tale classe contiene:
 * ''error_domain''. Una stringa nullable.
 * ''error_code''. Una stringa nullable.
 * ''error_message''. Una stringa nullable. Queste sono tutte a ''null'' se l'esito è buono, mentre sono valorizzate se si vuole indicare una eccezione.

Non ha altri membri da valorizzare se l'esito della replica è positivo.

----
Line 100: Line 174:
 * ...

----
Viene definita la classe interna !CoordinatorReplicaReserveResponse. Si tratta di una classe serializzabile che implementa l'interfaccia segnaposto (vuota) IPeersResponse. Serve come risposta solo per la richiesta 'replica_reserve'. Tale classe contiene:
 * ''error_domain''. Una stringa nullable.
 * ''error_code''. Una stringa nullable.
 * ''error_message''. Una stringa nullable. Queste sono tutte a ''null'' se l'esito è buono, mentre sono valorizzate se si vuole indicare una eccezione.
 * ...
 * ''bookings''. Lista di liste di Booking. Essendo questa la risposta ad una richiesta di record per i livelli da ''lvl'' in su, l'elemento ''i''-esimo di questa lista va assegnato al membro ''bookings[i + lvl]'' della nostra memoria.
 * ''max_eldership''. Lista di int. L'elemento ''i''-esimo va assegnato al membro ''max_eldership[i + lvl]'' della nostra memoria.

Modulo Coordinator - Dettagli Tecnici

Requisiti

L'utilizzatore del modulo Coordinator inizializza il modulo richiamando il metodo statico init di CoordinatorManager. In tale metodo viene anche passata l'istanza di INtkdTasklet per fornire l'implementazione del sistema di tasklet.

Quindi il nodo istanzia il suo CoordinatorManager passando al costruttore:

  • peers_manager. L'istanza di PeersManager.

  • map. La mappa delle posizioni libere.

Quando il nodo ha completato la fase di bootstrap, l'utilizzatore del modulo chiama il metodo bootstrap_complete del CoordinatorManager.

Quando il nodo considera che la notifica della sua presenza abbia ormai raggiunto tramite ETP tutti i membri del g-nodo in cui è entrato, l'utilizzatore del modulo chiama il metodo presence_notified del CoordinatorManager.

Deliverables

Nel costruttore del CoordinatorManager viene creata una istanza di CoordinatorService (che descriveremo sotto) e viene registrata nel PeersManager.


Il modulo permette di chiedere ad un vicino del nodo informazioni sui posti liberi nei suoi g-nodi con il metodo get_neighbor_map di CoordinatorManager.

Il metodo ha come argomento lo stub per contattare il vicino. Prevede l'eccezione StubNotWorkingError.

Restituisce una istanza di ICoordinatorNeighborMap.


Il modulo permette di chiedere ad un vicino del nodo di prenotare per lui un posto nel suo g-nodo di livello l con il metodo get_reservation di CoordinatorManager.

Il metodo ha come argomento lo stub per contattare il vicino e il livello a cui fare richiesta. Prevede l'eccezione StubNotWorkingError e l'eccezione SaturatedGnodeError.

Restituisce una istanza di ICoordinatorReservation.

Comunicazioni tra vicini

Quando il modulo vuole chiedere ad un vicino informazioni sui posti liberi nei suoi g-nodi usa il metodo remoto retrieve_neighbor_map. Non ha argomenti. Non prevede eccezioni, oltre alle solite StubError e DeserializeError. Restituisce una istanza di ICoordinatorNeighborMap.

L'interfaccia ICoordinatorNeighborMap è esposta dal modulo. La classe che viene istanziata è NeighborMap, una classe serializzabile interna al modulo.


Quando il modulo vuole chiedere ad un vicino di prenotare per lui un posto nel suo g-nodo di livello l usa il metodo remoto ask_reservation. Ha come argomento il livello l. Prevede l'eccezione SaturatedGnodeError, oltre alle solite StubError e DeserializeError. Restituisce una istanza di ICoordinatorReservation.

L'interfaccia ICoordinatorReservation è esposta dal modulo. La classe che viene istanziata è Reservation, una classe serializzabile interna al modulo.

Servizio Coordinator

Classe server del servizio Coordinator

Il modulo deriva da PeerService la classe CoordinatorService.

Questa classe è interna al modulo. Contiene questi membri:

  • retrieve_cache_done. Booleano, inizializzato a False.

  • my_presence_should_be_known. Booleano, inizializzato a False.

  • bookings. Lista di liste di Booking. Memoria delle prenotazioni. Contiene levels elementi. L'elemento i-esimo è la lista di prenotazioni attive per il nostro g-nodo di livello i+1. La classe Booking ha una posizione (int pos) e un time-to-live (Timer ttl). E' una classe serializzabile e interna al modulo.

  • max_eldership. Lista di int. Contiene levels elementi. L'elemento i-esimo dice il valore più alto di progressione già assegnato ad una prenotazione per un nuovo g-nodo di livello i dentro il nostro g-nodo di livello i+1. Un valore più alto significa che il g-nodo è arrivato dopo, cioè esso è più giovane.

Quando viene chiamato il metodo bootstrap_complete del CoordinatorManager, la classe CoordinatorService fa queste operazioni:

  • Riceve come argomento lvl il livello del g-nodo appena costituito dal nostro nodo.

  • Se lvl = levels:

    • Imposta il suo flag retrieve_cache_done.

  • Altrimenti:
    • In una nuova tasklet:
      • Avvia le operazioni di recupero dei record di sua pertinenza. Trattandosi di un servizio non opzionale, non attende l'evento PeersManager.participant_maps_ready.

      • Costruisce la richiesta r di tipo "retrieve_cache" dal livello lvl+1 in su.

      • Avvia il primo recupero con il metodo PeersManager.begin_retrieve_cache

      • Attende l'esito, cioè il booleano restituito, la risposta resp da interpretare, l'oggetto IPeersContinuation cont da passare nelle chiamate successive.

      • Se respnull:

        • Si accerta che resp.bookings.size = resp.max_eldership.size = levels - lvl. Altrimenti emette un warning e ignora questa risposta.

        • Per i da 0 a resp.bookings.size-1:

          • j = lvl + i.

          • Per ogni Booking bresp.bookings[i]:

            • Se bbookings[j]:

              • Aggiungi b a bookings[j].

          • Se resp.max_eldership[i] > max_eldership[j]:

            • max_eldership[j] = resp.max_eldership[i].

      • Se l'esito è True:

        • While True:
          • Avvia un altro recupero con il metodo PeersManager.next_retrieve_cache passando la IPeersContinuation cont.

          • Attende l'esito, cioè il booleano restituito e la risposta resp da interpretare.

          • Se respnull:

            • In base a resp modifica i propri membri bookings e max_eldership, come sopra.

          • Se l'esito è False:

            • Esci dal ciclo.
      • Al termine imposta il suo flag retrieve_cache_done.

Quando viene chiamato il metodo presence_notified del CoordinatorManager, la classe CoordinatorService fa queste operazioni:

  • Imposta il suo flag my_presence_should_be_known.

Il metodo is_ready() della classe CoordinatorService si basa sui flag retrieve_cache_done e my_presence_should_be_known.

Metodo reserve

Ricordiamo che quando una richiesta ad un servizio peer-to-peer viene ricevuta dall'hash_node viene chiamato il metodo exec della classe che deriva la PeerService. Questa riceve una istanza di IPeersRequest e deve restituire una istanza di IPeersResponse.

Se il metodo exec della classe CoordinatorService viene chiamato con una istanza di CoordinatorRequest (si veda sotto) che ha il membro name = 'reserve' allora abbiamo ricevuto una richiesta di "prenota un posto nel tuo g-nodo di livello lvl". Le operazioni da fare sono:

  • Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione DeserializeError. Inclusi errori nei valori accettabili di lvl.

  • Atomic on: queste operazioni devono essere eseguite atomicamente, senza permettere la schedulazione di altre tasklet.
  • Verifica nella mappa map del CoordinatorManager quali posizioni sono libere nel livello lvl. Se nessuna posizione risulta libera, lancia una eccezione.

  • Dalla lista ottenuta di posizioni libere, esclude quelle presenti nelle prenotazioni bookings(lvl-1) del CoordinatorService. Nello scorrere questa lista, rimuove le istanze di Booking che sono scadute (membro ttl). Se nessuna posizione risulta libera, lancia una eccezione.

  • Scegli una posizione pos.

  • Segnala la prenotazione nella memoria. Cioè crea una istanza di Booking pos con ttl a 20 secondi (una private const nel codice) nella lista bookings(lvl-1) del CoordinatorService.

  • Incrementa di 1 la max_eldership(lvl-1) nella memoria.

  • Con i dati in memoria prepara la risposta ret (pos=pos, eldership=max_eldership(lvl-1))

  • Atomic off.
  • Avvia la prima replica con il metodo PeersManager.begin_replica. Questi sono gli argomenti:

    • Come q mettiamo 15 (una private const nel codice).

    • Come perfect_tuple il valore ottenuto con il metodo perfect_tuple della classe CoordinatorClient con la chiave lvl.

    • Costruisce la richiesta r di tipo 'replica_reserve' per la posizione pos con anzianità eldership dentro il nostro g-nodo di livello lvl.

  • Attende l'esito, cioè il booleano restituito, la risposta resp da interpretare, l'oggetto IPeersContinuation cont da passare nelle chiamate successive.

  • Il booleano restituito è False solo se si è avuta l'eccezione NoParticipantsInNetwork. In questo caso si ignora la risposta resp.

  • La risposta resp dovrebbe essere semplicemente OK, cioè una istanza di CoordinatorReplicaReserveResponse con i membri a null. Altrimenti va prodotto un warning descrittivo da usare nella fase di debug del modulo; quando il modulo è stabile questa situazione va semplicemente ignorata.

  • Se l'esito è True:

    • Avvia la seconda replica con il metodo PeersManager.next_replica passando la IPeersContinuation cont.

    • Attende l'esito, cioè il booleano restituito e la risposta resp da interpretare.

    • Il booleano restituito è False solo se si è avuta l'eccezione NoParticipantsInNetwork. In questo caso si ignora la risposta resp.

    • La risposta resp dovrebbe essere semplicemente OK. Altrimenti va prodotto un warning descrittivo.

    • Se l'esito è True:

      • Avvia una tasklet in cui:
        • While True:
          • Avvia una replica con il metodo PeersManager.next_replica passando la IPeersContinuation cont.

          • Attende l'esito, cioè il booleano restituito e la risposta resp da interpretare.

          • Il booleano restituito è False se abbiamo completato q repliche o se si è avuta l'eccezione NoParticipantsInNetwork. In questo caso si ignora la risposta resp.

          • La risposta resp dovrebbe essere semplicemente OK. Altrimenti va prodotto un warning descrittivo.

          • Se l'esito è False:

            • Esci dal ciclo. Termina la tasklet.
  • Completa ret con (elderships=anzianità dei miei g-nodi da lvl in su)

  • Restituisce ret.

Metodo replica_reserve

Se il metodo exec della classe CoordinatorService viene chiamato con una istanza di CoordinatorRequest (si veda sotto) che ha il membro name = 'replica_reserve' allora abbiamo ricevuto una richiesta di "replica per una prenotazione del posto pos con anzianità eldership nel nostro g-nodo di livello lvl". Le operazioni da fare sono:

  • Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione DeserializeError. Inclusi errori nei valori accettabili di lvl e pos.

  • Atomic on.
  • Segnala la prenotazione nella memoria. Cioè crea una istanza di Booking pos nella lista bookings(lvl-1) del CoordinatorService.

  • Se max_eldership(lvl-1) < eldership:

    • Imposta max_eldership(lvl-1) = eldership.

  • Atomic off.
  • Restituisce OK.

Metodo retrieve_cache

Se il metodo exec della classe CoordinatorService viene chiamato con una istanza di CoordinatorRequest (si veda sotto) che ha il membro name = 'retrieve_cache' allora abbiamo ricevuto una richiesta di "recupera i record delle prenotazioni dal livello lvl in su", con 0 < lvllevels. Le operazioni da fare sono:

  • Se ci sono problemi a deserializzare gli argomenti viene fatta pervernire una eccezione DeserializeError. Inclusi errori nei valori accettabili di lvl.

  • Prepara ret con gli elementi da lvl-1 in su della lista bookings di CoordinatorService e con gli elementi da lvl-1 in su della lista max_eldership di CoordinatorService.

  • Restituisce ret.

Classe client del servizio Coordinator

Il modulo deriva da PeerClient la classe CoordinatorClient.

Ridefinisce il suo metodo perfect_tuple. La chiave che può essere usata per calcolare l'hash_node è un intero l da 1 a levels. La lista di interi restituita è composta da l volte il valore 0.

Classi serializzabili per le comunicazioni

Viene definita la classe interna CoordinatorRequest. Si tratta di una classe serializzabile che implementa l'interfaccia segnaposto (vuota) IPeersRequest. Serve per tutte le richieste che possono essere fatte al servizio. Tale classe contiene:

  • name. Una stringa che identifica la richiesta. I valori possibili sono: ['reserve', 'retrieve_cache', 'replica_reserve'].

  • reserve_lvl. Usato se name = 'reserve'. Un intero che indica il livello del g-nodo dentro il quale riservare un posto.

  • cache_from_lvl. Usato se name = 'retrieve_cache'. Un intero che dice di passare i record da quel livello in su.

  • replica_lvl. Usato se name = 'replica_reserve'. Un intero che dice il livello del g-nodo dentro il quale è stato prenotato un posto.

  • replica_pos. Usato se name = 'replica_reserve'. Un intero che dice la posizione della prenotazione.

  • replica_eldership. Usato se name = 'replica_reserve'. Un intero che dice l'anzianità del posto prenotato.


Viene definita la classe interna CoordinatorReserveResponse. Si tratta di una classe serializzabile che implementa l'interfaccia segnaposto (vuota) IPeersResponse. Serve come risposta solo per la richiesta 'reserve'. Tale classe contiene:

  • error_domain. Una stringa nullable.

  • error_code. Una stringa nullable.

  • error_message. Una stringa nullable. Queste sono tutte a null se l'esito è buono, mentre sono valorizzate se si vuole indicare una eccezione.

  • pos. Un intero. La posizione assegnata.

  • elderships. Una lista di interi. Le anzianità da l-1 (del g-nodo appena assegnato) fino a levels.


Viene definita la classe interna CoordinatorReplicaReserveResponse. Si tratta di una classe serializzabile che implementa l'interfaccia segnaposto (vuota) IPeersResponse. Serve come risposta solo per la richiesta 'replica_reserve'. Tale classe contiene:

  • error_domain. Una stringa nullable.

  • error_code. Una stringa nullable.

  • error_message. Una stringa nullable. Queste sono tutte a null se l'esito è buono, mentre sono valorizzate se si vuole indicare una eccezione.

Non ha altri membri da valorizzare se l'esito della replica è positivo.


Viene definita la classe interna CoordinatorRetrieveCacheResponse. Si tratta di una classe serializzabile che implementa l'interfaccia segnaposto (vuota) IPeersResponse. Serve come risposta solo per la richiesta 'retrieve_cache'. Tale classe contiene:

  • error_domain. Una stringa nullable.

  • error_code. Una stringa nullable.

  • error_message. Una stringa nullable. Queste sono tutte a null se l'esito è buono, mentre sono valorizzate se si vuole indicare una eccezione.

  • bookings. Lista di liste di Booking. Essendo questa la risposta ad una richiesta di record per i livelli da lvl in su, l'elemento i-esimo di questa lista va assegnato al membro bookings[i + lvl] della nostra memoria.

  • max_eldership. Lista di int. L'elemento i-esimo va assegnato al membro max_eldership[i + lvl] della nostra memoria.

Netsukuku/ita/docs/ModuloCoordinator/DettagliTecnici (last edited 2015-12-02 09:12:54 by lukisi)