MokaByte
Numero 05 - Febbraio 1997
|
|||
|
|
||
Fabrizio Giudici |
seconda parte | ||
Nella scorsa puntata abbiamo visto in generale le caratteristiche e le possibilità di impiego degli Agenti Mobili. Esistono numerosi linguaggi che consentono di implementare Agenti Mobili, ma Java, grazie alle sue intrinseche caratteristiche di portabilità e sicurezza, si candida a diventare il linguaggio per creare codice capace di spostarsi attraverso Internet. Esistono diversi progetti per realizzare Agenti Mobili in Java, ma mentre la maggior parte di essi esiste in versione puramente prototipale, se non addirittura solo sulla carta, IBM sta lavorando a quello che attualmente è più avanti nel suo sviluppo: stiamo parlando degli Aglets, con i quali avevamo terminato la puntata precedente. Oggi entreremo più nel dettaglio e vedremo come costruire un primo Aglet funzionante per provarlo su Internet!
Aglets: concetti base
Il progetto degli Aglet, sviluppato dal Tokyo Research Laboratory dell'IBM, è principalmente composto da due componenti:
il protocollo ATP (Agent Transfer Protocol) che permette di trasferire agenti mobili attraverso Internet.
Il modello ad oggetti degli Aglet
Il modello ad oggetti degli Aglet definisce un insieme di astrazioni ed di comportamenti per usare la tecnologia ad agenti mobili in reti geografiche come Internet. Le astrazioni fornite in questo modello sono:
Aglet.
E' un oggetto mobile capace di trasferirsi sui vari computer una rete.
è autonomo, poiché ogni volta che arriva su una macchina,
gli viene assegnato un thread di esecuzione privato, ed attivo,
in quanto è in grado di rispondere a messaggi provenienti dall'esterno
(anche da altri aglet).
Context.
E' l'ambiente dove opera un aglet. E' un oggetto stazionario (cioé
non mobile) che fornisce le infrastrutture per mantenere e gestire gli
aglet in un ambiente di esecuzione uniforme. Tra le altre cose, il context
si preoccupa anche di proteggere il computer che ospita gli agenti mobili
da eventuali attacchi, con una filosofia simile a quella del SecurityManager
di Java. Un computer può ospitare più di un contesto.
Proxy.
E' un oggetto in grado di rappresentare un aglet ed agisce come schermo
che "protegge" l'aglet dall'accesso diretto dei suoi metodi pubblici. Il
proxy fornisce anche trasparenza di locazione per l'aglet: può
essere usato per interagire direttamente con un aglet indipendentemente
da dove questo si trovi.
Message.
E' un oggetto che può essere scambiato tra più aglet. Lo
scambio di messaggi può essere usato dagli aglet per collaborare
e scambiarsi informazioni di qualsiasi tipo. E' possibile scambiare messaggi
sia in modo sincrono che asincrono
Itinerary.
E' il percorso che un aglet segue durante un suo viaggio.
Identifier.
E' un oggetto unico ed immutabile che viene associato ad ogni aglet esistente
per tutta la sua vita al fine di identificarlo in modo univoco.
Modello comportamentale di un aglet
Il modello ad oggetti degli aglet prevede i seguenti comportamenti elementari: creazione, clonatura, rilascio in rete, ritiro, disattivazione, attivazione, scambio di messaggi.
La
creazione di un aglet viene eseguita in un dato contesto. Al nuovo
aglet viene assegnato un identificatore univoco, poi esso viene inserito
nel contesto in cui é stato creato ed inizializzato, richiamando
dei metodi opportuni. L'aglet incomincia l'esecuzione vera e propria del
programma ad esso associato subito dopo la sua inizializzazione.
La
clonatura di un aglet fornisce una copia quasi identica dell'aglet
originale, che si trova inizialmente nello stesso contesto dell'aglet di
partenza. Le uniche differenze sono l'assegnazione di un identificatore
diverso e nel fatto che nel nuovo aglet il programma associato riprende
la sua esecuzione dall'inizio. I thread di esecuzione infatti non vengono
clonati.
Il
rilascio in rete di un aglet rimuove l'aglet dal suo attuale contesto
e lo inserisce nel contesto destinazione. Sia il codice delle classi che
la struttura dati vengono automaticamente serializzate e trasferite attraverso
la rete per mezzo del protocollo ATP (Aglet Transfer Protocol). Quando
il trasferimento è stato completato, viene creato un nuovo thread
per l'aglet (i thread di esecuzione non migrano), che può
cosi' riprendere la sua esecuzione. Quando un aglet viene rilasciato in
rete, si dice anche che esso viene spinto (pushed) nel suo nuovo
contesto.
Il
ritiro di un aglet lo rimuove dal suo attuale contesto e lo inserisce
nel contesto dal quale e' stato ordinato il suo ritiro (che non e'
necessariamente il contesto dove l'aglet e' stato creato originariamente).
In questo caso, si dice che un aglet =e' stato "tirato" (pulled).
Il concetto di agent pulling non e' comune a tutti i linguaggi di
programmazione di Agenti Mobili (ad esempio non esiste nel linguaggio Telescript
di cui abbiamo parlato il mese scorso), ma e' importantissimo per operare
attraverso un firewall. Se la macchina dalla quale l'aglet e' stato
lanciato e' nascosta dietro un firewall, l'aglet non potrebbe mai
tornare a casa autonomamente, dal momento che la sua "casa" non sarebbe
visibile dal sito "esterno" dove l'aglet e' stato mandato ad operare. Il
problema e' risolto se l'iniziativa di ritirare l'aglet viene presa esplicitamente
dalla sua "casa". Ovviamente le operazioni attraverso un firewall
prevedono l'uso di un proxy (un proxy di protocollo, da non
confondere con il proxy degli aglet).
La
disattivazione di un aglet è la possibilità di rimuoverlo
temporaneamente dal suo attuale contesto per immagazzinarlo in un dispositivo
di memorizzazione di massa (per esempio un file sull'hard disk).
L'aglet di fatto viene "congelato" a tempo indeterminato. In un qualsiasi
momento puo' venire riattivato e proseguire il suo programma mantenendo
lo stato che aveva prima del congelamento.
L'attivazione
di un aglet è l'operazione inversa alla disattivazione, cioé
il ripristino di un aglet a partire dalla sua immagine memorizzata in un
file con il suo reinserimento in un contesto (che non e' necessariamente
quello in cui e' stato disattivato).
Lo
scambio di messaggi tra aglet consiste nello spedire, ricevere
e gestire messaggi sia sincronamente che asincronamente.
Si e' detto che i thread associati agli aglet non possono essere clonati e non possono migrare. Questo implica che il programma associato ad un aglet riparte daccapo ogni volta che l'aglet viene spostato. Tanto per fare un esempio, questo comportamento e' completamente differente dalla sospensione e riattivazione dei processi che si puo' fare in un sistema UNIX con i comandi kill -stop e kill -cont. Tuttavia questo fatto non contraddice la proprieta' degli agenti mobili di conservare il loro stato di esecuzione, che e' stata descritta nell'articolo del mese scorso: infatti lo stato delle variabili viene preservato e, grazie ad opportuni metodi, e' possibile far proseguire il nuovo thread di esecuzione da un punto diverso per ogni nuova macchina che viene visitata.
La classe Aglet
La classe Aglet
e' ovviamente la classe piu' importante della J-AAPI. E' la classe astratta
che, mediante subclassing, permette di creare degli agenti mobili
personalizzati, mediante ridefinizione di alcuni metodi che vengono invocati
in momenti ben precisi della vita di un aglet (alcuni prima dell'evento,
altri dopo), come si vede nella seguente tabella:
Evento | Prima | Dopo |
Creazione | onCreation() | |
Clonatura | onCloning() | onClone() |
Rilascio | onDispatching() | onArrival() |
Ritiro | onReverting() | onArrival() |
Distruzione | onDisposing() | |
Disattivazione | onDeactivating() | |
Attivazione | onActivation() |
Abbiamo detto che, quando un aglet viene creato o quando arriva in un nuovo contesto, gli viene associato un nuovo thread di esecuzione. Il punto d'ingresso di questo thread èil metodo run(); da questo punto di vista, un aglet si comporta in maniera molto simile ad un applet tradizionale.
Un esempio
Vediamo ora di scrivere un aglet in grado di trasferirsi su una macchina remota, eseguire un compito e tornare indietro con i risultati del calcolo. Useremo in realta' due aglet distinti:
import aglet.*; |
Notiamo che il costruttore è vuoto. Questa è una regola da seguire sistematicamente per tutti i tipi di aglet: qualsiasi codice di inizializzazione va inserito in un metodo apposito che viene messo a disposizione dalle API (in questo caso initializeJob()). Inoltre, in generale non è possibile creare direttamente un aglet con l'operatore new, ma si deve operare per mezzo di appositi metodi messia a disposizione. Per esempio, per creare uno Slave bisogna utilizzare il metodo statico ibm.aglets.Slave.create() (come vedremo più avanti).
Proseguendo nell'analisi del nostro Slave, troviamo un campo ARGUMENT che viene ereditato ed è un istanza della classe Arguments. In pratica è una hashtable che può essere utilizzata per passare allo Slave argomenti a cui si può fare riferimento per nome. Nell'esempio viene recuperata una stringa di nome "arg 1".
Analogamente, il campo RESULT è un riferimento ad un oggetto al quale possiamo assegnare un valore qualsiasi che rappresenta il risultato dei calcoli dello Slave. Nell'esempio si è restituito il valore della stringa passata come argomento a cui è stato aggiunto il suffisso "DONE". Ovviamente in pratica si possono fare cose più complicate, ed in particolare si possono costruire strutture dati anche molto complesse (per esempio un grafo) che verranno automaticamente serializzate e trasmesse a destinazione
Per quanto riguarda
il Master, potete vedere un esempio di codice funzionante in figura 2.
import aglet.*; |
FIGURA 2: Il Master
Il metodo run() viene invocato subito dopo la creazione dell'aglet e si occupa di creare un'istanza di uno Slave, comunicandogli i parametri di lavoro e la destinazione. Il metodo Slave.create() si occupa automaticamente di trasferire lo Slave a destinazione una volta che è stato creato.
Gli indirizzi delle macchine destinazione sono di fatto delle URL che usano il protocollo ATP, per esempio atp://daisy.esng.dibe.unige.it:404. Generalmente la porta di riferimento è la 404 per i sistemi Windows, mentre per i sistemi Unix i progettisti dell'IBM consigliano di usare un numero di porta "elevato".
Il metodo handleMessage() viene utilizzato per gestire i messaggi in arrivo. Il modello comportamentale di uno Slave prevede che esso, una volta tornato a destinazione, spedisca al suo Master un messaggio di nome "result"=;, contenente la variabile RESULT di cui si è parlato prima, per comunicargli i risultati del suo calcolo. Nell'esempio i risultati del calcolo vengono semplicemente stampati sullo schermo.
Per concludere, l'eccezione lanciata dal metodo onDispatching() impedisce che il Mastervenga per errore spostato in un altro contesto, visto che questo non è il ruolo per il quale è stato creato.
Con poche righe di codice siamo stati in grado di costruire un Agente Mobile. Questo esempio dimostra come la creazione di semplici Agenti Mobili con il linguaggio Java sia veramente un processo facile ed immediato.
Dalla teoria alla pratica
Ora che ne sappiamo
abbastanza, vediamo come far funzionare il tutto. Per prima cosa dobbiamo
installare l'ultima versione del codice, disponibile sul sito primario
degli Aglet http://www.trl.ibm.co.jp/aglets.
Il codice viene distribuito sotto forma di archivio ZIP o TAR, che è
sufficiente estrarre in una qualsiasi directory di un disco rigido.
Attualmente vengono supportati gli ambienti Win32 (Windows 95 o Windows
NT) e Solaris (sia Sparc che Intel).
Nonostante il
package degli Aglets sia completamente scritto in Java, ci sono
dei problemi per poterlo eseguire su altre macchine UNIX. La causa di queste
difficoltà sta nel fatto che è necessario poter disporre
delle API di serializzazione e di Remote Method Invocation (RMI), che sono
parte integrante del JDK di Sun solo dalla versione 1.1, la quale non è
ancora disponibile per tutte le piattaforme. Esiste una versione "pre-beta"
di RMI per JDK 1.0.2, ma anche questa non è disponibile per tutti
i sistemi operativi.
Se si dispone di uno dei sistemi supportati, conviene abbinare il codice degli Aglets all'ultima versione del JDK 1.1, la beta 3. Sebbene i progettisti dell'IBM non abbiano ancora testato sufficialmente la compatibilità della JDK 1.1 beta 3, pare che non ci siano problemi sostanziali.
Una volta che si è estratto il tutto, è sufficiente lanciare lo script agletsd.bat (Windows) o agletsd (Unix) che si trova nella directory AWB/Aglets. E' necessario settare opportunamente le variabili d'ambiente AGLET_EXPORT_PATH ed AGLET_PATH, comunque dovrebbe essere sufficiente aggiungere i percorsi AWB/Aglets/lib ed AWB/Aglets/public alla variabile CLASSPATH
Quando si lancia agletsd viene mandato in esecuzione Tahiti, che è un workbench per gestire gli aglet mediante un'interfaccia grafica. Cliccando sul tasto "New" è possibile selezionare uno tra quattro aglet dimostrativi e lanciarlo in rete. Tahiti include anche un demone capace di ricevere e mandare in esecuzione aglet provenienti dalla rete.
Il più semplice di tutti gli aglet dimostrativi è il "Writer", un programmino che apre una finestra sulla macchina destinazione, visualizzando un messaggio. Premendo un pulsante sulla finestra, essa si chiude e l'aglet ritorna a casa.
E' possibile lanciare aglet personalizzati attaverso Tahiti semplicemente copiandoli nella directory AWB/Aglets/public/ibm/aglets/samples; comunque il nostro aglet di prova TestMaster può essere semplicemente lanciato con la solita sintassi a riga di comando java TestMaster. Sulla macchina destinazione è però necessario aver lanciato Tahiti che deve essere pronto a ricevere lo Slave
Per provare un aglet non è necessario avere un computer collegato in rete: si può sempre specificare l'indirizzo atp://localhost e fare eseguire i programmi localmente. Nel caso si voglia provare l'"ebbrezza" di un aglet che viaggia veramente attraverso la rete, bisogna disporre di due macchine su cui installare Tahiti, che fungerà da piattaforma di lancio su una e da stazione di ricezione dall'altra. Se non disponete di due macchine collegate in rete, ma per esempio di un solo computer connesso ad Internet attraverso un modem, è comunque possibile fare delle prove: al Networking Competence Center, che opera presso l'Università di Genova, è disponibile una macchina che è stata configurata per ricevere aglet da Internet e mandarle in esecuzione. Il suo indirizzo è atp://daisy.esng.dibe.unige.it:404. Molto probabilmente daisy è la prima macchina pubblicamente accessibile per scopi di sperimentazione, ma entro brevissimo tempo dovrebbero rendersene disponibili altre in vari centri di ricerca sparsi per il mondo.
Un avvertimento: con l'attuale release degli Aglets non è possibile operare da dietro un firewall. Questa limitazione verrà superata nel prossimo futuro.
Anche
per questo mese abbiamo finito. La prossima volta andremo più in
profondità, analizzando in particolare i meccanismi di scambio di
messaggi. Nel frattempo, chi volesse altre informazioni può consultare
la home page degli aglet all'IBM http://www.trl.ibm.co.jp/aglets,
oppure il sito http://www.javalounge.com
che ospita risorse aggiuntive, come una mailing list e codice dimostrativo.
Una pagina contenente informazioni sugli Aglet è in preparazione
all'indirizzo http://www.esng.dibe.unige.it/aglets.
|
||
|
||
MokaByte ricerca
nuovi collaboratori
|
||
|