250 likes | 436 Views
Java Spaces. JavaSpaces es parte de Jini (spec.). Jini es una colección de especificación de servicios Ayuda a que ellos se encuentren mutuamente en la red Máquinas provistas de Jini pueden encontrar servicios en la red a la cual se conectan y ofrecen los suyos
E N D
JavaSpaces es parte de Jini (spec.). • Jini es una colección de especificación de servicios • Ayuda a que ellos se encuentren mutuamente en la red • Máquinas provistas de Jini pueden encontrar servicios en la red a la cual se conectan y ofrecen los suyos • Las máquinas son clientes y servidores a la vez
Ejemplo ?
Services provistos por Jini Lookup Services (reggie) rmid JavaSpace (outriggger) Fiddler Mercury Norm Transaction Services (mahalo.jar) HTTP-Server (tools.jar)
¿ Qué provee Jini concretamente ? • Un espacio en el cual se pueden guardar objetos, recuperar o sacar una coipa de ellos. • Métodos : write, read, take, (readIfExists, takeIfExists) • Un mecanismo para proveer completitud de transacciones • Un mecanismo para notificación de eventos
Los métodos write y read write Space read A copy
El método take write Space X take Existe solo aquí
Cómo crear un JavaSpace en una máquina • Un JavaSpace puede crearse levantando el servicio outrigger de Jini con un nombre como parámetro. Este será el nombre del espacio. • Pero antes de poder levantar el outrigger hay que levantar: • El servidor http que viene en tools.jar • Un rmid • El servidor de lookup rigger • El servidor de transacciones mahalo
Comandos • java -jar c:\jini_1\tools.jar –dir C:\jini1_1 • rmid -J-Dsun.rmi.activation.execPolicy=none. • java -Djava.security.policy=policy.txt -jar C:\jini1_1\reggie.jar http://froebel:8080/reggie-dl.jar policy.txt reggie_log public • java -Djava.security.policy=policy.txt -jar $JINI/mahalo.jar http://froebel:8080/mahalo-dl.jar policy.txt txn_log public • java -Djava.security.policy=policy.txt -Djava.rmi.server.codebase=http://froebel:8080/outrigger-dl.jar -Dcom.sun.jini.outrigger.spaceName=JavaSpaces -jar C:\jini1_1\transient-outrigger.jar public
Como escribir objetos en el espacio • Las clases definidas por el usuario deben declarar que implementan la interfaz Entry. • Esto es solo una marca para decirle a Java que un objeto de esta clase puede ser escrito en un JavaSpace • Los campos (variables) en esta clase deben ser objetos. Si se necesitan primitivas (como nímeros enteros) deben usarse wrappers • Integer i = new Integer(4)
Ejemplo de una clase import net.jini.core.entry.Entry; public class Message implements Entry { public String content; public Integer counter; public Message() { //this is mandatory !!!!! } public Message(String content, int initVal) { this.content = content; counter = new Integer(initVal); } public String toString() { return content + counter + " times."; } public void increment() { counter = new Integer(counter.intValue() + 1); } }
Guardando objetos en un espacio import net.jini.core.lease.Lease; import net.jini.space.JavaSpace; import java.io.*; public class WriteMessages { public static void main(String[] args) { try { BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); JavaSpace space = SpaceAccessor.getSpace(); System.out.print("Message ? "); String m = in.readLine(); Message2 msg = new Message2(m,0); space.write(msg, null, Lease.FOREVER); } catch (Exception e) {e.printStackTrace(); } } }
Recuperando objetos import java.io.*; import net.jini.core.lease.Lease; import net.jini.space.JavaSpace; public class ReadMessage { public static void main(String[] args) { try { Message2 template; JavaSpace space = SpaceAccessor.getSpace(); BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Message (**=null)? "); String m = in.readLine(); template = new Message2(m); Message2 result = (Message2)space.read(template,null,Long.MAX_VALUE); System.out.println("Got "+result.toString()); } catch (Exception e) {e.printStackTrace(); } }
Reglas para recuperar objetos • EL objeto debe coincidir con la estructura y contenidos del template • Referencias a null actúan como comodines • No hay reglas para decidir qué objeto será recuperado si hay más de uno que coincide • Los parámetros: un objeto template, una transacción (por ahora null) y un timeout por si no se encuantra un objeto que coincida con el dado. Long.MAX_VALUE hace que se espere para siemre
Tomando objetos • Funciona igual que el read pero borra el objeto que se lee del espacio • Para evitar deadlocks o esperas demasiado largas existe readIfExists y takeIfExists • Su estructura es la misma que read y write pero retornarán de inmediato si no existe el objeto buscado • La clase SpaceAccessor con el método getSpace no es standard, la usamos para simplificar el código y la explicación en este curso
Un arreglo “distribuido” WriteElements index index content content index content ReadElements UpdateElements
Sincronizando clientes • Customer(.java) • Toma un número, • incrementa el Ticket Disp. • Toma el objeto de servicio • espera para ser servido • incrementa el número • de servicio • Un cliente será servido sólo • si tiene el objeto de número de • servicio • Al principio el prog. TicketInit crea • y pone en el espacio los dos objetos Ticket Dispenser number Service Number number
El Chatting Un objeto tail in indica cuál es el número del último mensaje para ese Channel Cada Message tiene un contenido y un número correlativo El canal identifica el „chat-thread“ Channel Message Tail number number Channel Message Message number number Channel Channel
Archivos: • Tail: implementa la clase del objeto que marca el número del último mensaje para un canal de chat • MessageChat: contiene un mensaje • CreateChannel: crea un “canal” de chat nuevo (con un nombre y tail en 0) • ChatSpace: programa que permite usar el espacio para el chat (ChatClient), inicia 2 threads (leer y escribir) • ChannelChatRead: lee mensajes del espacio para un channel determinado • ChannelChatWrite: escribe mensajes en el espacio para un channel determinado
Eventos Distribuidos 3- Un objeto que coincide el template entra en el espacio 4- El oidor es notificado 2- Notificar al servidor sobre el interés en recibir los eventos 1- Crear un objeto Listener
Cómo escribir un Listener import java.rmi.server.*; import java.rmi.RemoteException; import net.jini.core.event.*; import net.jini.space.JavaSpace; public class Listener implements RemoteEventListener { private JavaSpace space; public Listener(JavaSpace space) throws RemoteException { this.space = space; UnicastRemoteObject.exportObject(this); } public void notify(RemoteEvent ev) { Message template = new Message(); try { Message result = (Message)space.read(template, null, Long.MAX_VALUE); System.out.println(result.content); } catch (Exception e) { e.printStackTrace(); } } }
Un programa que escucha import net.jini.core.lease.Lease; import net.jini.space.JavaSpace; public class HelloWorldNotify { public static void main(String[] args) { JavaSpace space = SpaceAccessor.getSpace(); try { Listener listener = new Listener(space); Message template = new Message(); space.notify(template, null, listener, Lease.FOREVER, null); } catch (Exception e) { e.printStackTrace(); } } }
Llamando al método notify • Después de esto, cuando cualquier programa que escriba un mensaje en el espacio (no importa el contenido) el objeto Listener del programa HelloWorldNotify será „notificado“, esto es, el método notify será llamado Message msg = new Message(); msg.content = "Hello World"; space.write(msg, null, Lease.FOREVER);
Transacciones • Es un conjunto de operaciones que deben realizarse atómicamente, o sea, todas o ninguna. • En JavaSpaces se puede definir un conjunto de operaciones write, read, y take que deban ser realizadas de esta manera. • Para esto, un objeto transaction debe ser creado y pasado como parámetro con cualquier operación que deba pertenecer a la transacción • Una vez que todas las opreaciones write, read, take, con la misma transacción han sido “ejecutadas” una operación commit va a ejecutar todas o nunguna. • En el ultimo caso se lanza una exception
Ejemplo JavaSpace space = SpaceAccessor.getSpace(); TransactionManager mgr = TransactionManagerAccessor.getManager(); //get a reference to the transaction manager service Try { Transaction.Created trc = TransactionFactory.create(mgr, 3000); Transaction txn = trc.transaction; SharedVar template = new SharedVar(url); SharedVar counter = (SharedVar) space.take(template, txn, Long.MAX_VALUE); counter.increment(); space.write(counter, txn, Lease.FOREVER); txn.commit(); } catch (Exception e) { System.err.println("Transaction failed"); return; }