= Il modulo coord = ~+La classe '''{{{Node}}}'''+~ è usata come ''dataclass'' per la mappa {{{MapCache}}}. <
> Ha un attributo {{{alive}}}. Da questo dipende anche il metodo {{{is_free}}}, che serve per usare la classe nella {{{MapCache}}}. <
> Deve essere serializable, perché va passata via rete da un coordinator node al suo successore. ~+La classe '''{{{MapCache}}}'''+~ è una mappa che usa come dataclass gli oggetti {{{Node}}}. <
> Nel suo costruttore si copia tutti i nodi della {{{MapRoute}}} come nodi "alive". <
> Ha un dizionario {{{tmp_deleted}}} che memorizza i nodi temporaneamente cancellati (vedi sotto). Ha un metodo {{{node_add}}} per aggiungere un nodo alla mappa. Viene richiamato sull'evento {{{NODE_NEW}}} della {{{MapRoute}}}. Deve controllare se il nodo è libero. <
> Ha un metodo {{{node_del}}} per togliere un nodo dalla mappa. Viene richiamato sull'evento {{{NODE_DELETED}}} della {{{MapRoute}}}. == La classe Coord == Tutti i nodi che partecipano al servizio P2P Coordinator Node (tutti i nodi di Netsukuku) istanziano all'avvio un oggetto della classe '''{{{Coord}}}'''. La classe {{{Coord}}} eredita dalla classe {{{P2P}}} (vedi il [[../ModuloP2P|modulo p2p]]). <
> Nel suo costruttore riceve l'istanza di {{{Radar}}}, di {{{MapRoute}}} e del gestore {{{P2PAll}}}. Richiama il costruttore base di {{{P2P}}} impostandosi il PID = 1. Si registra sulla {{{P2PAll}}}. Si crea una istanza della classe {{{MapCache}}}, copiandosi i dati della {{{MapRoute}}}. In quanto {{{P2P}}} si era già creata una istanza di {{{MapP2P}}}. <
> Registra gestori per gli eventi {{{NODE_NEW}}} e {{{NODE_DELETED}}} della {{{MapRoute}}} e per l'evento {{{NODE_NEW}}} della {{{MapP2P}}}, rispettivamente i metodi {{{self.mapcache.node_add}}}, {{{self.mapcache.node_del}}} e {{{self.new_partecipant_joined}}}. <
> Si memorizza nell'attributo '''{{{coordnode}}}''' la lista dei coordinator nodes (per riferimenti futuri) per ognuno dei gnodi a cui appartiene. L'evento {{{NODE_NEW}}} nella {{{MapP2P}}} indica un nuovo partecipante al servizio P2P. Il metodo che gestisce l'evento, '''{{{new_partecipant_joined}}}''', è una microfunc. <
> Questo metodo stabilisce se il nodo nuovo diventa il nuovo Coordinator per uno dei gnodi a cui appartengo. Se è così, aggiorna il suo attributo {{{coordnode}}}. <
> Ogni nodo, quindi, ha '''sempre''' la lista aggiornata dei Coordinator Nodes per tutti i gnodi, ai vari livelli, a cui appartiene. Ogni nodo di Netsukuku riceve, tramite ETP, le informazioni che sono necessarie a conoscere costantemente la topologia della rete. Però queste informazioni possono arrivare con un certo ritardo. L'obiettivo del Coordinator Node è quello di fare da referente per la situazione attuale di un gnodo. <
> Per essere precisi, le informazioni che il Coordinator Node deve coordinare non sono tutte quelle presenti nella mappa di routes di un nodo, come il gateway, la REM eccetera. E' sufficiente il dato "{{{alive}}}", cioè se il nodo con ID = x esiste. Per questo ogni nodo tiene aggiornata una seconda mappa, la '''{{{MapCache}}}'''. <
> Quella che veramente ha valore, in un dato momento, è la {{{MapCache}}} del nodo che in quel momento è il Coordinator Node. <
> Quando un nodo, nel metodo {{{new_partecipant_joined}}}, si accorge che prima lui era il Coordinator Node ed ora lo è un altro, esso si incarica di passare la sua {{{MapCache}}} al nuovo Coordinator Node. <
> Questo realizza, per il servizio Coordinator Node, quanto descritto nel documento Ntk_p2p_over_ntk.pdf riguardo l'ingresso di nuovi partecipanti che vanno a sostituire il vecchio "hash node". <
> '''''TODO''': Manca ancora, rispetto al documento citato, il meccanismo dei nodi backup e l'ottimizzazione descritta dopo di questo "subentro".'' Il metodo '''{{{h}}}''' dice quale è l'indirizzo "perfetto" del coordinatore del gnodo di un certo livello e indirizzo. <
> Ad esempio, il coordinatore per il gnodo 1.2 di livello 2 è 1.2.0.0, cioè {{{h((2, [None, None, 2, 1])) = [0, 0, 2, 1]}}}. <
> I valori degli ultimi livelli del NIP passato sono irrilevanti. === Metodi del servizio P2P Coordinator Node === Il metodo '''{{{going_out}}}''' riceve i parametri {{{lvl}}}, {{{id}}}, {{{gnumb=None}}}. Se lo ricevo significa che sono il coordinator node del gnodo {{{G}}} di livello {{{lvl + 1}}} a cui appartiene il nodo {{{N}}}. <
> {{{N}}} vuole uscire dal gnodo, per poi entrare in uno con numerosità {{{gnumb}}}. Gli diamo risposta affermativa se {{{gnumb is None}}} o se {{{gnumb < |G|}}}. <
> La numerosità del gnodo ({{{|G|}}}) viene calcolata usando il {{{node_nb}}} della mappa {{{mapcache}}}. Viene tolto 1 per simulare la rimozione del nodo. <
> Se i criteri sono soddisfatti viene rimosso il nodo {{{N}}} dalla nostra mapcache e viene restituito il numero attuale di nodi presenti in {{{G}}} (la risposta è affermativa). <
> Altrimenti viene restituito {{{None}}}. Il metodo '''{{{going_out_ok}}}''' riceve i parametri {{{lvl}}}, {{{id}}}. Il nodo {{{N}}} comunica così che ha completato l'hook in un altro gnodo. Ricevuta questa conferma il coordinator node rimuove il nodo dalla lista dei "temporaneamenti rimossi". '''''TODO''': La lista dei temporaneamente rimossi non viene in effetti usata per gli undo.'' Il metodo '''{{{going_in}}}''' riceve i parametri {{{lvl}}}, {{{gnumb=None}}}. Se lo ricevo significa che sono il coordinator node del gnodo {{{G}}} di livello {{{lvl + 1}}} in cui vuole entrare il nodo {{{N}}}. Inoltre, siccome quando viene chiamato il coordinator node significa che quel gnodo non è vuoto, si assume che se lo ricevo sono anche un membro di quel gnodo. '''''TODO''': non sarebbe più sicuro tralasciare questa assunzione e aggiungere il parametro id?'' <
> {{{N}}} vuole entrare nel gnodo, perché pensa che abbia numerosità {{{gnumb}}}. Gli diamo risposta affermativa se {{{gnumb is None}}} o se {{{gnumb < |G|}}}. <
> La numerosità del gnodo ({{{|G|}}}) viene calcolata usando il {{{node_nb}}} della mappa {{{mapcache}}}. Viene aggiunto 1 per simulare la aggiunta del nodo. <
> Se i criteri non sono soddisfatti viene restituito {{{None}}}. <
> Se i criteri sono soddisfatti si cerca di aggiungere il nodo. Si vede quali sono gli ID liberi per il livello {{{lvl}}}; se non ce ne sono viene restituito {{{None}}}. <
> Se ci sono ID liberi viene generato un NIP valido e viene restituito il nuovo NIP assegnato in {{{G}}} (la risposta è affermativa).