Agentes en Grid

El año pasado participé del desarrollo de una aplicación que se ejecuta en una grilla de máquinas sin disco. Este año, estoy volviendo a actualizar el proyecto, espero poder bloggear sobre el resultado dentro de un mes. Mientras, quisiera escribir sobre algunas ideas a explorar.

En este post, uso el término “agente”, de una forma algo libre. No definiré precisamente el concepto, quiero usarlo como término base a refinar en el futuro (llegando en algún momento a tratar el tema de agentes autónomos, que me parece más interesante). Por ahora, exploremos algunas ideas básicas (¿ingenuas?) para entender mejor los problemas relacionados con agentes y aplicaciones en grid. Algunas de las ideas acá presentadas pueden ser vistas como ingenuas, pero siento que es un ejercicio necesario, para aprehender los conceptos clave y los problemas a ser resueltos en este tipo de aplicaciones. Al final de este post, presentaré algunas sugerencias de implementación.

He descripto algunas aplicaciones para ejecutar en una grid en mis anteriores post:

Grid Computing Programming

Más programando para una grid

Programando para una Grid

Conceptos de Agentes

En este post, un agente es una pieza de software, con conducta y estado. Se ejecuta en un host de agentes, una aplicación que provee los servicios de base para que el agente pueda “vivir” y trabajar. Representaremos al agente con esta figura:

Patrones de comunicación de agentes

Hay mucha literatura sobre comunicación de agentes, desde simples técnicas hasta elaborados contratos, negociaciones, y más. Podemos tener agentes con creencias, deseos e intenciones. En este post, un agente es más simple: sólo tiene estado, puede enviar y recibir mensajes. Puede recibir estímulos de otros agentes y desde el ambiente de su host.

El más simple patrón de comunicación es un agente enviando un mensaje a otro agente:

Algunas notas:

- El agente enviador conoce al agente receptor. Quiero decir, alguna forma de identidada debe ser implementada. El mensaje no es enviado a cualquiera: el que envía intenta enviar el mensaje a un determinado agente.

- El mensaje transporta datos, y debe ser entendido por el receptor, posiblemente procesado por uno de sus métodos de implementación.

- En enviador no espera por una respuesta. No está interesado en un mensaje de respuesta inmediato.

- Los agentes pueden residir en diferentes máquinas en la grila, y la comunicación se produce tanto local como remota.

Durante su vida un agente puede enviar muchos mensajes a distintos agentes, que debe conocer de alguna manera:

Algunas veces, el agente enviador recibirá un mensaje desde el agente receptor, notificando algun trabajo hecho, o enviando algún dato procesado. Dependiendo de la aplicación, el mensaje de respuesta podría acarrear información para identificar al mensaje original:

En este caso, el enviador original debe estar preparado para recibir la respuesta de una manera asincrónica. Esto podría ser un interesante problema a resolver: un agente puede enviar varios mensajes, y sería mejora si puede seguir ejecutando sin recibir todas las respuestas a tiempo. Por ejemplo, en una aplicación de un juego de tablero, un agente puede delegar la exploración de un árbol de jugadas a otros agentes, y, luedo de un tiempo, sería posible tomar una decisión, con sólo algunas respuestas recibidas.

Nubes (“clouds”) en el cielo de la grilla

Otro caso: un agente puede estar interesado en enviar un mensaje, pero no a un receptor determinado. Al contrario, quiere enviarlo a una “nube” de agentes, así cualquiera interesado en el mensaje tendría la oportunidad de procesarlo.

Esta característica puede ser implementada usando estas estrategias:

- Un agente envía un mensaje a un sistema de pizarra (blackboard), que otros agentes están vigilando.

- Una agente enviaría una mensaje a la aplicación host, indicando un tópico (como en una cola de mensajes), así cualquier agente subscripto recibirá el mensaje. Una variante: sólo algunos subscriptores reciben el mensaje, dependiendo de parámetros de aplicación.

- Un agente podría enviar un mensaje dirigido a alguna definición de proveedor de servicio. Un proveedor de servicio es un agente, que declara al comienzo de su vida, sus capacidades y los servicios que puede proveer. 

Un ejemplo, tomemos una aplicación de un juego de tablero, ajedrez o go. Un agente en esa aplicación puede enviar un mensaje reclamando resolver cierta posición de ataque. En un sistema de pizarra, publicará el pedido. En un sistema de tópicos, lo enviaría al tópico “ataques”. En una estrategia de proveedor de servicio, envía el mensaje a uno o más de los proveedores del servicio AttackResolver.

Como en el patrón anterior, un agente puede recibir una respuesta asincrónica, ahora desde “la nube”:

 

Duplicación de agentes

Un agente tiene conducta y estado. Si el agente puede dividir su trabajo, podría tomar el camino de duplicarse a sí mismo:

Es algo extraño, pero podría ser útil, dependiendo de la aplicación a desarrollar.

Agentes y la Grilla

Cada agente puede ser albergado en un nodo de la grilla. El mecanismo de envío de mensajes debe ser capaz de enviar un mensaje a otro nodo. La aplicación host mantiene una lista de agentes por identidad, y conoce cúal  es local o remoto. Una prueba ácida: una aplicación de grilla con agentes debe ser capaz de correr en una sola máquina, o en una grilla, sin cambiar el código o el algoritmo.

 

Como en otras implementaciones de grilla (discutidos en los post que mencioné al principio), un servidor central está a cargo de la distribución de las tareas entre los nodos de la grilla. “Grid as a Service” es una nueva frase que podemos aplicar a esta situación.

Moviendo al Agente

Un agente puede iniciar sus actividades en un node. Pero en algún momento, puede decidir de continuar su trabajo en otro nodo (la aplicación host que lo alberga también puede tomar esa decisión, independientemente del agente). Entonces, su estado sería enviado de un nodo a otro (otro caso: podría querer duplicarse y que su clon siga el trabajo en otra máquina).

Noten que la conducta del agente (que puede estar compilada o puede estar escrita en un lenguaje dinámico o de agente), no viaja. Pero bien podría ser que viaje, incluso, que haya agentes que vayan adaptando su conducta en el tiempo.

Inyectando conducta

La conducta de cada agente podría ser expresada en código compilado (archivos .jar en Java, assemblies en .NET). Otras alternativas son posibles: la conducta podría ser especificada en un lenguaje de scripting dedicado a agentes (pienso en una adaptación del AjBasic, por ejemplo).

Si la conducta se expresa en forma compilada, uno o varios servers puede tomar la responsabilidad de almacenar y distribuir esos componentes:

Ideas de implementación

Muchas de estas ideas pueden ser implementadas en cualquier lenguaje/tecnología apropiada, como Java y .NET, que soporte múltiples threads, invocación remota, serialización de mensajes, etc…

En los últimos tiempos estuve trabajando en mis projectos AjMessages y AjAgents, más información enestos post:

AjMessages: a message processor

Agents using Concurrency and Coordination Runtime (CCR)

AjMessages- hacia un procesador de mensajes

Agentes usando Concurrency and Coordination Runtime (CCR)

Algoritmos Genéticos con AjAgents y Concurrency and Coordination Runtime (CCR)

Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)

(Tengo otro proyecto, AjGrid, no publicado aún). Para este post, creo que el AjAgents podría ser una implementación de esas ideas. AjMessages tiene ahora soporte de ejecución remota, pero está más orientado a un proceso tubería (“pipeline”): es más difícil de implementar en semejante sistemas las ideas de este post.

Estoy agregando algunas características a AjAgents (ahora, AjAgents trabaja sólo en local):

- Configuración: Carga y creación de agentes en ejecución, según alguna información de configuración, ya sea al inicio o en el medio de la ejecución.

- Assembly remoto: Así un nodo de grilla pueder ser inyectado con nuevos agentes.

- Identificación de Agente: Para identificar al agente de manera única (un UID debería bastar).

- Transporte de mensaje: Windows Communication Foundation es un candidato, otro podría ser DSSP.

Un posible camino es tomar Decentralized System Services (DSS) del Microsoft Robotics Developer Studio. Un agente podría ser implementado como un servicio de DSS, ejecutando en un host DSS. La comunicación entre máquinas puede ser implementada usando DSSP como protocolo.

“Stay tuned”, vendrá más código.

(Esta es una actualización y traducción de mi post en “Anglish”, Angel’s English:

Agents in a Grid

)

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

This entry was posted in 6148, 6149, 7338. 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>