Scribble Distribuido con Microsoft Robotics Developer Studio y DSS

Estuve jugando con el nuevo CTP release de Microsoft Robotics Developer Studio. Tiene nuevas características, como instalación y ejecución de un diagrama de Visual Programming Language en muchos nodos.

Para explorar algo de esta nueva funcionalidad, escribí el sueño de todo programador: un programa de dibujo distribuido multiusuario…;-)… Bueno, es uno bastante simple, pero funciona, y puede ejecutarse en varias máquinas, exponiendo y compartiendo nuestros más inspirados dibujos de mouse. El código puede ser descargado desde aquí.

El proyecto

Tengo la versión 1.5 del MSRS y el nuevo CTP MRDS (nueva sigla), ejecutándose en la misma máquina, sin mayores problemas. Comencé creando un nuevo proyecto del tipo Simple Dss Service RDS 2008:

El proyecto contiene un service component llamado DssScribble, y un Windows form, que está a cargo del dibujo:

Al comienzo del service component, crea el formulario, y lo connecta para usar los ports y su cola de dispatcher:

protected override void Start() { base.Start(); // Add service specific initialization here. WinFormsServicePort.Post(new RunForm(CreateForm)); } private Form CreateForm() { return new CanvasForm(_mainPort, linePort, TaskQueue); }

Cada línea que el usuario dibuja en la ventana es enviada al service component, para ser distribuido a cada subscriptor interesado en el dato:

[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> PostLineHandler(PostLine postLine) { SendNotification<PostLine>(_submgrPort, postLine); yield break; }

Las líneas son recibidas en el NewLineHandler (el modo de conectar dos componentes es via VPL, como veremos más adelante). El linePort es el port para comunicarse con la instancia del formulario:

[ServiceHandler(ServiceHandlerBehavior.Exclusive)]
public IEnumerator<ITask> NewLineHandler(NewLine newLine) { linePort.Post(newLine.Body); newLine.ResponsePort.Post(DefaultUpdateResponseType.Instance); yield break; }

El service component no tiene estado. Uso una clase para transportar la información de las nuevas líneas a dibujar y distribuir:

[DataContract()]
public class DssScribbleState { } [DataContract()] public class DssScribbleLine { [DataMember()] public int fromX; [DataMember()] public int fromY; [DataMember()] public int toX; [DataMember()] public int toY; public DssScribbleLine() { } public DssScribbleLine(int fromX, int fromY, int toX, int toY) { this.fromX = fromX; this.fromY = fromY; this.toX = toX; this.toY = toY; } }


Dibujando con VPL


El Visual Programming Language es una herramienta fascinante, lleno de “features”. Se puede arrastrar y soltar services components desde la toolbar. Cuando esta herramienta es lanzada, se puede buscar el DssScribble service en el área inferior izquierda:



Arrastré dos instancias del DssScribble service component, y las renombre a DssScribble1 y DssScribble2:



Conecté las instancias, así pueden escuchar sus notificaciones. Cada línea producida en una instancia es transmitida a la otra. De esta manera, lo que dibujemos en una ventana, aparecerá en la otra.


La conexión es entre la notificación PostLine y la notificación NewLine:



Para lanzar la aplicación, ir al menú Run -> Start. Aparece una ventana, mostrando el log de mensajes:



Esperamos unos momentos, y dos instancias del componente DssScribble son creados, cada uno mostrando un formulario. Podemos dibujar en cualquiera de los dos, arrastrando el mouse, siendo reproducido el dibujo en el otro formulario:



Este es mi autorretrato: una lágrima se me escapa, de la emoción de un dibujo distribuido…. ;-)


Ejecutando en nodos distribuidos


La IDE del VPL IDE tiene un diseñador de nodo. A la derecha, hay una rama Node en el árbol del proyecto. Cada nodo representa un DSS host conteniendo servicios DSS. Agregué dos nodos, el primero conteniendo una instancia del Scribble y arrastré la segunda instancia al segundo nodo:



Noten el panel inferior derecho: definí ahí las propiedades para el nodo Windows0, en el mismo localhost, pero con otras puertas (el primer nodo correrá en las puertas 50000/50001). En otro proyecto, probé tener una máquina remota, y la aplicación distribuida funcionó sin problemas. Podemos definir varios nodos, cada uno en una máquina distintas, poner en ellos instancias de DssScribble, enlazarlas por notificaciones, y podemos dibujar con nuestro compañeros de trabajo…. ;-)


Para ejecutar la aplicación en forma distribuida, se debe compilarla. Usar el menú Build -> Compile as a Service . Debe ingresarse un directorio donde generar el código y la solución. Entonces, la herramienta VPL compila solución, y genera los paquetes de instalación. Se puede abrir la solución generada con Visual Studio (el código es muy interesante, bastante astuto, implementando, por lo que ví, una máquina de pila, ver los métodos Decrement, Increment).


Cada nodo debe tener corriendo un servicio llamado package deployer, que ejecuta en otra puerta (la misma para todos los nodos, el valor asumido es 55555). Ir a ejecutar el directorio bin de Microsoft Robotics Developer Studio, y ejecutar el rundeployer.cmd:



 


Nota: si queremos compilar el servicio de nuevo, debemos parar el deployer: el generador de código usa el directorio bin y trae conflictos con el deployer andando.


Ahora, estamos listos para distribuir nuestra “killer app”: ejecutar Run -> Run on distributed nodes. El sistema avisa de tener los deployers ya andando:



Y la magia comienza: cada nodo es contactado, y la aplicación es instalada en ellos. Un nodo DSS es iniciado en cada nodo, y sus correspondientes instancias de servicios son creadas. En este ejemplo, tendremos dos nuevas ventanas de consola, ejecutando cada una un nodo DSS. Esta es la ventana de mi segundo nodo:



Ahora, cada noda muestra su ventana de dibujo, y la diversión comienza…. :-)


Notas


No estoy usando partners en este ejemplo. En cambio, uso notificaciones de eventos, en este caso, nuevas líneas, así otros componentes pueden recibir esas notificaciones. Podemos escribir otros componentes, otras ventanas de dibujo, para recibir y procesar las líneas. Una idea es usar las coordenadas de una nueva línea para controlar el motor de un robot, o para persistir las líneas producidas usando un componente de persistencia nuestro. Para controlar el motor de un robot, podemos usar VPL, sin necesidad de reescribir el componente original.


Conclusiones


Usando VPL podemos componer nuevas aplicaciones usando componentes ya existentes. Podemos crear nuestras propias actividades. Y usando diagramas de nodos (en VPL o usando el DSS Manifest Editor) con el packager deployer, podemos distribuir la aplicación en muchos físicos nodos, en cualquier manera que creamos conveniente. Pero debemos definir cada nodo y componente: no hay facilidades para programar una grilla, con nodos dinámicos. Una aplicacion gridificada para DSS puede ser escrita, pero en mi opinión, debe ser creada con código nuestro. Idea para explorar: escribir una aplicación de control, usando package deployer, instalara tareas en los nodos en una grilla.


Todas estas herramientas abrieron mi cabeza. Escribir DSS services components es una nueva forma de pensar y programar, algo que quise explorar por años: cómo escribir objetos con un proceso de mensajes de una vía, en una forma distribuida y paralala (AjAgents está motivado por esa objetivo). Me imagino un sistema que modele las ideas de Minsky sobre la mente humana.


Bueno, es un nuevo mundo. Dorothy: no estamos más en Kansas… ;-)


Angel “Java” Lopez
http://www.ajlopez.com

This entry was posted in 1389, 7337, 7747. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>