Aglets e Agentes Móveis Aluno: Rodrigo Moreira Barbosa (aluno de mestrado) Orientador: Prof. Dr. Alfredo Goldman vel Lejbman DCC/IME/USP Projeto InteGrade Demanda por soluções de problemas computacionalmente complexos. Abordagens tradicionais: – Supercomputadores – Máquinas Paralelas – Recentemente: aglomerados Projeto InteGrade (cont.) Aglomerados custam muito caro Em geral, passam a maior parte do tempo ociosos Ocupam muito espaço Fazem muito barulho, esquentam Desperdício de recursos ambientais Somos um país pobre: não podemos nos dar ao luxo de jogar recursos fora desta forma Projeto InteGrade (cont.) Qualquer empresa, universidade, instituição possui muitos computadores que ficam ociosos a maior parte do tempo. Por que não disponibilizar esse tempo de processamento ocioso para execução de tarefas que exijam grande uso de recursos computacionais? Projeto InteGrade (cont.) Criação de um middleware para interligar estes computadores em uma grade. InteGrade: Projeto da USP, PUC-Rio e UFMS. Projeto InteGrade (cont.) Linhas de Pesquisa: – Arquitetura geral do sistema (CORBA) – Segurança – Monitoração de recursos (processador, memória, disco, rede, hardware específico etc.) – Identificação de padrões de uso e ociosidade • entender o passado para prever o futuro – Execução de diferentes classes de algoritmos paralelos – Integração com sistemas ubíquos – Criação de uma infra-estrutura para agentes móveis Projeto InteGrade (cont.) Por que agentes móveis no InteGrade? – Agentes móveis podem ser utilizados para execução de tarefas que necessitem de recursos presentes em diferentes nós da grade. – Diminuir ainda mais a ociosidade dentro de uma rede, permitindo que programas isolados possam ser executados como agentes móveis, executando em máquinas ociosas e migrando sempre que essas são requisitadas pelo usuário, reiniciando na próxima máquina a execução do ponto onde ela havia sido suspensa. Nossa proposta inicial Utilizar agentes móveis para encapsular tarefas longas que não necessitem se comunicar com outras tarefas. Essas tarefas constituiriam se tornariam agentes oportunistas, tentando diminuir ainda mais a ociosidade da grade e fariam a busca por máquinas ociosas de forma autônoma. O ambiente de execução dos agentes móveis deve ser o mais leve possível e deve minimizar a sobrecarga da migração. O que são agentes móveis Agentes móveis são programas que podem ser despachados de um computador e transferidos para outro computador, continuando sua execução. Por que Aglets? Aglets é atualmente o sistema de agentes móveis mais utilizado. Aglets é muito bem avaliado como plataforma para agentes móveis. [AGKSW2000] Existem pessoas no IME já utilizando Aglets (Roberto Speicys Cardoso e Leo K. Ueda ) Aglets O Aglets foi desenvolvido inicialmente pela IBM, tendo à sua frente os pesquisadores Mitsuro Oshima, Guenter Karjoth, Kouichi Ono. Atualmente é mantido por uma iniciativa de código aberto: (aglets.sourceforge.net) The Aglets Software Development Kit O Aglets Software Development Kit é um ambiente para programação de agentes móveis em Java Aglets são objetos Java que podem mover-se de uma máquina para outra na rede. Ou seja, um aglet que executa em um dado computador, pode repentinamente parar sua execução, despachar-se para uma uma máquina remota, e começar a executar de novo. The Aglets Software Development Kit (cont.) Aglets fornece o mecanismo de migração fraca, já que não preserva pilha de execução das linhas de execução do aglet, devido a limitações da JVM. No entanto, o estado dos objetos do aglet são mantidos. Visão geral da API do Aglets Diagrama Visão Geral da API do Aglets (cont.) com.ibm.aglet.Aglet: A classe abstrata que define os métodos fundamentais usados para controlar a mobilidade e ciclo de vidas dos agentes móveis. Alguns métodos elementares e sua semântica: – dispose (): Descarta o objeto – dispatch (URL): Despacha o aglet para o destino especificado na URL – deactivate (long duration): Instrui o aglet para armazenar a si mesmo em uma mídia persistente. – getAgletInfo (): Obtém informações sobre o aglet Visão Geral da API do Aglets (cont.) com.ibm.aglet.AgletId: Objeto que mantém um identificador único, enquanto encapsula seus detalhes de representação. com.ibm.aglet.AgletProxy: Essa interface age com um “gancho” para o aglet e fornece um modo comum de acessar o aglet por detrás dele. Garante a segurança do aglet e a transparência de localização. – AgletContext.getAgletProxies() – AgletContext.getAgletProxy(AgletID) – Aglets.getAgletProxy(String contextName, AgletID) Visão Geral da API do Aglets (cont.) com.ibm.AgletContext: Provê uma interface para o ambiente de execução que o aglet ocupa. Quando o aglet é despachado, a referência para o contexto antigo é desfeita e a referência para o novo contexto é atada a ele quando de sua chegada. Visão Geral da API do Aglets (cont.) com.ibm.aglet.Message: Os aglets se comunicam trocando objetos desta classe. Uma mensagem tem uma String para especificar o tipo da mensagem e um objeto arbitrário. com.ibm.aglet.Ticket: Serve para especificar como um aglet é transferido: destino, protocolo, timeout, integridade, etc. Este objeto deve ser utilizado onde a URL é utilizada como meio de especificar destino. Visão Geral da API do Aglets (cont.) com.ibm.aglet.FutureReply: Objeto retornado por uma transmissão assíncrona de mensagem. Serve para a verificação de chegada de alguma resposta. Estendendo a classe Aglet Linhas gerais: – estender a classe com.ibm.aglet.Aglet – Pode estender outra classe que implementa Aglet – Não pode sobrescrever os métodos dispatch () e getAgletContext(), declarados como final. – Não pode implementar um construtor, visto que a classe Aglet é inicializada depois da instanciação. Deve-se utilizar o método onCreation (), ao invés do construtor. Estendendo a classe Aglet (cont.) void Aglet.onCreation (Object init): Método chamado somente uma vez na vida do aglet, quando de sua criação. Utilizado para inicializar o aglet. void Aglet.onDisposing (): Chamado depois do dispose (). Utilizado para desalocar os recursos locais utilizados pelo aglet antes de sua morte. void Aglet.run (): Método chamado sempre que uma instância é criada ou reiniciada. Bom lugar para se definir a tarefa comum. boolean Aglet.handleMessage (Message msg): Trata mensagens recebidas. Se a mensagem é tratada devolve true, caso contrário devolve false. Estendendo a classe Aglet (cont.) public class HelloAglet extends Aglet { public void onCreation(Object init) { System.out.println("created!"); } public void run() { System.out.println("hello!"); } public boolean handleMessage(Message msg) { if (msg.sameKind("sayHelloAgain") { System.out.println("hello!"); return true; } return false; } public void onDisposing() { System.out.println("bye!"); } } Ciclo de vida dos Aglets Ciclo de vida dos Aglets (cont.) AgletContext.createAglet (URL codebase, String name, Object init) -> Aglet.onCreation (Object init) Aglet.clone () Aglet.dispatch (atp://aglets.ibm.com:1434/context_name) Aglet.deactivate (long timeout) Aglets não podem ser recolhidos pela JVM. Sendo assim, devem ser mortos explicitamente pelo dispose (). Eventos do Aglet e Modelo de Delegação Visto que a JVM não permite, por motivos de segurança, que se acesse a pilha de execução de uma linha de execução, é impossível armazená-la para permitir o reinício da execução a partir dela. Sendo assim, Aglets só suporta migração fraca, visto que não é interessante desviar-se da versão padrão da JVM. Aglets usa um esquema de eventos para permitir a implementação de uma ação que emula a migração. Eventos do Aglet e Modelo de Delegação (cont.) Eventos do Aglet e Modelo de Delegação (cont.) import com.ibm.aglet.Aglet; import com.ibm.aglet.event.MobilityEvent; import com.ibm.aglet.event.MobilityListener; class MyListener implements MobilityListener { public void onDispatching(MobilityEvent l) { closeWindow(); closeFile(); } public void onReverting(MobilityEvent l) { openWindow(); donNextJob(); } public void onArrival(MobilityEvent l) { } } public class MyAglet extends Aglet { public void onCreation(Object init) { MobilityListener listener = new MyListener(); addMobilityListener(listener); } } Eventos do Aglet e Modelo de Delegação (cont.) When Event Object Listener Method called Just before cloning CloneEvent CloneListener onCloning When clone is created CloneEvent CloneListener onClone After creation of clone CloneEvent CloneListener onCloned Just before dispatch MobilityEvent MobilityListener onDispatching Just before retraction MobilityEvent MobilityListener onReverting destination MobilityEvent MobilityListener onArrival Just before deactivation PersistencyEvent PersistencyListener onDeactivating After activation PersistencyEvent PersistencyListener onActivation After arrival at the Mobilidade de Objetos Quando um aglet é despachado, clonado ou desativado, ele é transformado em um fluxo de bytes e então restaurado dele depois. Aglets usa o mecanismo de serialização para criar o fluxo de bytes e recriar o objeto. Estes objetos devem implementar então a interface java.io.Serializable ou java.io.Externalizable, ou referenciados como transient. Mobilidade de Objetos (cont.) class ListingAglet extends Aglet { // result and its contents are transferred. private Vector result = new Vector(); transient InputStream in = new InputStream(); // will not be transferred } Mobilidade de Objetos (cont.) Objetos movidos por valores Objetos movidos por referência: Mobilidade de Objetos (cont.) class Transferrable implements java.io.Serializable { Hashtable hash; // Hashtable is also serializable } class NotTransferrable { int dummy; } class MyClass extends Aglet { transient FileDescriptor fd; // never get transferred. int value; // moved by value String str; // moved by value Object transferable = new Transferrable(); // move by value Object not_transferable = new NonTransferable(); // throws NotSerializableException. AgletProxy proxy; // moved by reference } Mobilidade de Objetos (cont.) Variáveis de classe: public class MyAglet { static int class_variable = 0; public void onCreation(Object init) { class_variable = 10; dispatch("atp://next.place"); } public void run() { if (class_variable != 10) { System.out.println("Class variable never get transferred!"); } } } Mobilidade de Objetos (cont.) Transferindo Objetos RMI: – Referências para objetos RMI não são perdidas com a migração. – Todavia, Aglets não suporta migração de servidores RMI. Passagem de mensagens Aglet.handleMessage (): MyAglet extends Aglet { public boolean handleMessage(Message msg) { if (msg.sameKind("doJob")) { doJob(); } else if (msg.sameKind("shutdown")) { deactivate(0); } } } Passagem de mensagens (cont.) Now-type: String answer = proxy.sendMessage(new Message("question")); System.out.println(answer); Future-type: FutureReply future = proxy.sendAsyncMessage(new Message("question")); int num_task = 10; // do private job at most 10 times while waiting for the result. while(future.isAvailable() == false && num_task-- >0) { doPrivateJob(); } System.out.println( (String)future.getReply() ); Passagem de mensagens (cont.) Oneway-type: Nos outros tipos de envio, se um objeto envia uma mensagem para si mesmo, ela é colocada no início da fila. Com a Oneway, a mensagem é colocada sempre no fim da fila. proxy.sendOnewayMessage (new Message (“question”)); Passagem de mensagens (cont.) Se o handleMessage () devolve false, o remetente da mensagem recebe uma NotHandledException. Future future = proxy.sendAsyncMessage(); ... try { Object reply = future.getReply(); } catch (NotHandledException ex) { // the receiver didn't handled the message } catch (MessageException ex) { // an exception has been thrown in the receiver's handleMessage() System.out.println(ex.getException()); } Passagem de mensagens (cont.) Mensagens em Aglets suportam o recurso de enviar ciência, antes mesmo de terminar de tratar a mensagem. public boolean handleMessage(Message msg) { if (msg.sameKind("accessDB")) { openDB(); // pseudo code Object reply = accessDB(msg.getArg()); msg.sendReply(reply); closeDB(); return true; // i know this message... } return false; // false, otherwise } Mensagens de Sincronização public StackAglet extends Aglets { static int capacity = 10; Object stack[] = new Object[capacity]; int num = 0; public handleMessage(Message msg) { if (msg.sameKind("push")) { push(msg); } else if (msg.sameKind("pop")) { pop(msg); } else if (msg.sameKind("isFull")) { msg.sendReply( num == capacity); } else if (msg.sameKind("isEmpty")) { msg.sendReply( num == 0 ); } else return false; Mensagens de Sincronização (cont.) private void push(Message msg) { while (num == capacity) { waitMessage(); } stack[num++] = msg.getArg(); if (num==1) { notifyMessage(); // wake up "pop" message } } private void pop(Message msg) { while(num==0) { waitMessage(); } msg.sendReply(stack[--num]); if (num == (capacity -1)) { notifyMessage(); // wake up "push" message } } } Visão Geral da Arquitetura Visão Geral da Arquitetura(cont.) Camada de tempo de execução Aglets – Serialização e desserialização de aglets. – Carregamento de classes e transferência – Gerenciamento de referências e recolhimento de lixo. Visão Geral da Arquitetura(cont.) PersistenceManager CacheManager SecurityManager Visão Geral da Arquitetura(cont.) Camada de comunicação: – Derivada do padrão OMG, MASIF (Mobile Agent System Interoperability Facility) Visão Geral da Arquitetura(cont.) Estrutura de objetos Aglets – Message Manager – Resource Management – Recolhimento de lixo Referências Javadoc da API do Aglets Aglets Specification Draft 1.1 – http://www.trl.ibm.com/aglets/spec11.htm Site do projeto Aglets – http://aglets.sourceforge.net [AGKSW2000] – Using Mobile Agents in Real World: A Survey and Evaluation of Agents Plataforms (Josef Altmann et. al) Site do InteGrade: – http://gsd.ime.usp.br/integrade Mobile Agents: Are they a good idea? – http://citeseer.nj.nec.com/chess95mobile.html