Recently, I was involved in the development of an application that runs on a grid of diskless machines. I was an exciting project, and now, after the rush of shipping it, I want to write down some ideas to explore.
In this post, I use the term “agent”, that is a bit fuzzy. I won’t define precisely the concept, I want to use as a base term to refine in a future. By now, let explore some basic (naive?) ideas to better understanding of the problems related to agents and grid applications. Yes, some ideas presented here could be viewed as naive, but I feel that this is a needed exercise, to grasp the key concepts and problems to be solved in these kind of applications. At the end of this article, I’ll present some implementation suggestions.
I described some applications to run in a grid in my previous post:
In this post, agent is a piece of software, with behaviour and state. It runs inside an agent host, a host application that provides the base services so an agent can “live” and run. An agent will be represented as in this drawing:
Agent communication patterns
There is a lot of literature about agents communication, from simple techniques to elaborated ones as contracts, bids, and more. We can have agents with beliefs, desires and intention. In this post, an agent is simpler: only an object with state, that can send messages. It can receive stimula from other agents and from the host environment.
The simplest communication pattern is composed of an agent sending a message to another agent:
- The sender agent knows the receiver agent. That is, some form of identity must be implemented. The message is not send to anyone: the sender intention is to send the message to a determined receiver.
- The message carries data, and it must be understood by the receiver, possibly invoking one of its methods.
- The sender doen’t wait for a response. It’s not interested in a return message or data.
- The agents could reside in different physical machines in the grid, in a transparent way.
During its life an agent can send many messages to differents target agents, each one is a known agent for the sender:
Sometimes, the sender agent will receive a message from the receiver agents, notifying some work done, or informing some processed data. Depending on the application, the response message could carry information to identify the original message:
In this case, the sender must be prepared to receive the response in an asynchronous way. This could be an interesting problem to solve: an agent can send many messages, and it would be better if it can still run without receiving all the responses in time. For example, in an board game application, one agent could delegate some tree branch exploring to other agents, and, after some time, it should be able to take a decision, without all the information.
Clouds in the grid sky
Now, another case: an agent could be interested in send a message, without forward it to a determined receptor. Instead, it could be send to a cloud of agents, so anyone interested in the message could have the opportunity of processing it.
(Ok, I’m a bit odd creative in my drawings…
This feature could be implemented using these strategies:
- An agent could send a message to a blackboard system.
- An agent could send a message to host application, indicating a topic (like in a message queue), so any subscribed agent will receive the message. An variant: only some subscriptors receive the message, depending on application settings.
- An agent could send a message targeting some service provider definition. A service provider is an agent that declares, at the beginning of its life, its capabilities and service that is capable to provide.
As example, we could take a chess/board game application (I prefer the game of go). An agent in such application can send a message reclaiming to solve some attack position. In a blackboard system, it will publish the request in the blackboard. In a topic system, it deposits the message on topic “attackers”. In a service provider strategy, it sends the message to one or many AttackService provider.
As in the previous pattern, an agent can receive an asynchronous response, now from “the cloud”:
An agent has behaviour and state. If the agent must fork its jobs, it could take the way of duplicating itself:
It’s a bit strange action, but it could be useful, depending on application at hand.
Agents and the Grid
Each agent can be hosted in a grid node. The message sending mechanism must be able to send a remote message to another node. The host application keeps a list of agents by identity, and knows which one is local or remote. An acid test: a grid application with agents must be able to run all in one machine, or in grid, without changing the code or algorithm.
As in another grid implementations (discussed in my previous post), a central server is in charge of distributing the tasks between the grid nodes. That server could receive tasks from outside application or even, from other grid. “Grid as a Service” is a new buzzword to apply.
An agent can initiate its activities in one node. But at point, it can decide to continue the work in another node (the host application in that node could take that decision, too). Then, its state should be send from one node to another.
Note that the agent behaviour (perhaps implemented in compiled code) doesn’t travel.
The behaviour of each kind of agent could be expressed in compiled code (.jar files in Java, assemblies in .NET). Other alternatives are possible: the behaviour could be specified in a specific scripting agent language.
If the behaviour is expressed in compiled form, one or more servers have the responsability of storing and distributing that components:
Most of these ideas can be implemented in any appropiate language/technology, like Java and .NET, that supports multi threading, remote invocation, message serialization, etc…
Last months I was working on my pet projects AjMessages and AjAgents, more info at previous posts:
(I have a new project, named AjGrid, not published yet). For this post, I guess that AjAgents could be an appropiate implementation. AjMessages now has remote support, but it’s more oriented to a pipeline processing: it’s difficult to implement in such disposition some of the above ideas.
I must add some features to AjAgents (actually, AjAgents is a local, proof of concept implementation):
- Configuration: Load and creation of agents in runtime, from a configuration file, or on the fly, in the middle of a run.
- Remote assembly: So a grid node can be injected with new agents.
- Agent identification: To identify an agent in a unique way (an UID could be a solution).
- Message transport: Windows Communication Foundation is a candidate.
But another approach is to take Decentralized System Services (DSS) from Microsoft Robotics Studio. An agent can be implemented as a DSS Service, running in a DSS Host. The intermachine communication would be implemented using DSSP as protocol.
Stay tuned, to see some code in the coming weeks.
Angel “Java” Lopez