La classe Channel
E' un wrapper della classe stackless.channel.
Oltre ai metodi send e recv, che richiamano i metodi send e receive dello stackless.channel incapsulato, fornisce i metodi sendq e recvq.
La particolarità di questi due metodi è che il chiamante del metodo sendq non resta mai bloccato. Vediamo meglio.
Con la normale classe stackless.channel quando una tasklet (termine equivalente a microthread) sta in ascolto con il metodo receive per un messaggio che non è stato ancora inviato, questa tasklet si blocca.
Quando una tasklet invia un messaggio con il metodo send su un canale dove nessuno sta in ascolto questa tasklet chiamante viene bloccata.
Invece, usando la classe Channel e il metodo sendq, tramite l'uso dell'attributo balance del channel si evita che, nel caso sopra descritto, le chiamate vengano accodate alla maniera classica. Invece si memorizzano in una lista che il metodo recvq prenderà in considerazione.
Questo comportamento è molto importante in alcuni punti critici del programma Netsukuku.
Ad esempio viene usata nelle definizione di funzioni microfunc per far si che ci sia un solo microthread per l'esecuzione di una certa funzione, che in esso le varie chiamate siano eseguite in sequenza e che, allo stesso tempo, il chiamante di quella funzione non risulti mai bloccato dalla chiamata. Il microthread incaricato di eseguire queste chiamate in sequenza nel programma netsukuku è chiamato dispatcher.
Con il semplice uso di stackless.channell, quando una tasklet richiama una funzione microfunc in un momento in cui il dispatcher è ancora impegnato da una precedente chiamata, questa tasklet chiamante risulterebbe bloccata. Questo non va bene al programma netsukuku.
Tramite l'uso della classe Channel e del metodo sendq le chiamate vengono immediatamente memorizzate nella lista (o coda) del Channel e il dispatcher le prenderà in considerazione non appena potrà usando il metodo recvq.
Un altro metodo fornito dalla classe Channel è bcast_send. Con questo metodo si invia un messaggio a tutte le tasklet in ascolto sul Channel.
Per definizione, questo metodo non bloccherà mai la tasklet che effettua l'invio. TODO: Meglio usare send invece di sendq e una while invece di un for.
Un altro modo di usare la classe Channel è quello di istanziarla usando il costruttore con micro_send=True.
Di nuovo quello che si vuole ottenere è che l'invio di un messaggio non risulti bloccante per il microthread che lo fa. Questa volta però lo si ottiene iniziando un nuovo microthread ad ogni messaggio che si invia sul channel.
Questo metodo è usato in particolare nel microthread che gestisce la funzione ManageSockets - vedi spiegazione dettagliata nella pagina del modulo microsock.