Agents on the move

Bolster your client apps by adding agent mobility

Last month we delved into the world of agents. We learned what they are and what problems they solve. We also developed the foundation for a simple agent architecture in Java. I promised that we'd build on that foundation in the coming months, and here I am, making good on that promise.

Recall that agents typically possess one or more of the following characteristics; they can be:

  • Autonomous
  • Adaptive/learning
  • Mobile
  • Persistent
  • Goal oriented
  • Communicative/collaborative
  • Flexible
  • Active/proactive

We've got a lot of ground to cover, so we'd best get started. We're going to start our agent adventure with an up-close look at agent mobility. Agent mobility provides a good starting point because the problems associated with mobile (and potentially untrustworthy) code are well-known, and robust solutions are readily available. In addition, Java (via remote method invocation -- or RMI -- and object serialization) provides prefabricated tools that make the job of moving objects easier.

Location, location, location

To better understand mobile agents and their behavior, we must first look briefly at traditional network architectures. The following figure illustrates the network behavior of a typical client/server application.

The typical client/server application communicates via requests and responses, which require a round trip trek across the network.

A client/server application typically consists of two pieces: a client piece and a server piece. Often, the client and server pieces are on separate machines and they communicate over a common network. When the client needs data or access to resources that the server provides, the client sends a request to the server over the network. The server in turn sends a response to the request. This "handshake" occurs again and again in a traditional client/server architecture. Each request/response requires a complete round trip across the network.

Now compare the client/server architecture I just described to the mobile agent architecture illustrated in the next figure.

In the mobile agent architecture, the client actually migrates to the server to make a request directly, rather than over the network.

Just as in the client/server architecture, there is a client piece and a server piece. The difference lies in how the two communicate. When the client in the mobile agent architecture needs data or access to a resource that the server provides, the client doesn't talk to the server over the network. Instead, the client actually migrates to the server's machine. Once on the server's machine, the client makes its requests of the server directly. When the entire transaction is complete, the mobile agent returns home with the results.

A mobile agent's travel habits

One distinguishing characteristic of a mobile agent architecture is (surprise, surprise) the mobility of the code. However, while this characteristic is necessary, it alone is not sufficient. That's because the idea of moving code and computation to the location of the data and resources is not unique to the mobile agent architecture. In fact, such mobility has been a feature of many commercial databases for some time. In the database world, mobile code goes by the name of a stored procedure. A stored procedure is a piece of client code that executes on the server. In some applications, the client piece of the application can dynamically upload stored procedures to the server. Once there, they can do their work and return the results of their calculations back to the client.

What's the difference then between mobile agents and stored procedures? Stored procedures lack many of the features common to agents such as autonomy and flexibility. A more compelling reason, however, involves the type of mobility. Stored procedures are basically static entities: Once they're uploaded to a server they belong to that server. If a transaction requires data or access to resources spread across several servers, a stored procedure is forced to traverse the network just as the client piece did in the traditional model shown earlier. In other words, a stored procedure cannot migrate from server to server, dragging along the incomplete transaction or calculation with it. A mobile agent can and does.

Client/server architectures vs. mobile agent architectures: Which approach is best and why?

I've provided some interesting background on mobile agents, but nothing (at least yet) that indicates why we might want to move code from the client to the server rather than have the two communicate over a network. As we learned last month, there are three very good reasons.

First, mobile agents solve the client/server network bandwidth problem. By moving a query or transaction from the client to the server, the repetitive request/response handshake is eliminated.

Second, agents reduce design risk. Agents allow decisions about the location of code (client vs. server) to be pushed toward the end of the development effort when more is known about how the application will perform. In fact, the architecture even allows for changes after the system is built and in operation.

Third, agent architectures also solve the problems created by intermittent or unreliable network connections. Agents can be built quite easily that work "off-line" and communicate their results back when the application is "on-line".

Inside a mobile agent

A mobile agent is really a gestalt entity composed of two different pieces. One piece is the code itself, which consists of the instructions that define the behavior of the agent. The second piece is the current state of execution of the agent.

Often, these two pieces are separate. For example, in a typical computer program, the code sits on disk while the executing state sits in RAM. A mobile agent, however, brings the two together. When an agent migrates to a new host, both its code and its state are transferred. Thus, the agent doesn't only remember what to do and how to do it, it remembers what it was doing before as well.

When an agent migrates to a new host, both of these pieces must be captured and packaged. In the discussion that follows and the code examples included with this column, the two pieces are referred to as resource (the code) and data (the state). The resource piece consists of the class files that define the agent. The data piece consists of a snapshot of the agent's state. More technically, it consists of a snapshot of the agent's data structures.

The lifecycle of a mobile agent

Agents have a well-defined lifecycle. The figure below illustrates the four states that make up this lifecycle.

An agent's lifecycle

If the state diagram looks suspiciously similar to the state diagram of an applet, it's because the lifecycles of both applets and agents are similar. In fact, I find that applets are a lot like non-mobile agents. That's a useful consideration to remember.

Here's what happens in each of the four states:

initializePerforms one-time setup activities such as building initial data structures
startStarts its calculations
stopStops its calculations, saves intermediate results, joins all threads, and stops
completePerforms one-time termination activities

The agent on the move

Mobile agents migrate between computing locations called hosts. Agent hosts are responsible for providing the resources agents need to work. Agent hosts are also responsible for handling the mechanics of packaging an agent and moving its resource and data pieces from one host to another. The following figure illustrates how this occurs.

Agent hosts communicate with each other to move the agent along its way

There are two hosts in this figure: the remote host and the local host. The local host is responsible for orchestrating the transfer. The remote host is responsible for initiating the transfer -- possibly at the request of the agent itself. The agent initially resides on the remote host. When the series of communications is complete, the agent will reside on the local host.

The communication goes as follows:

  1. The remote host notifies the local host of its desire to transfer an agent by invoking the remote agent's requestToSend() method.

  2. The local host marks the beginning of the transfer by invoking the remote host's beginTransfer() method. The remote host in turn invokes the agent's stop() method. When the stop() method returns, the agent is ready for transfer.

  3. The local host gets the resource piece of the agent by invoking the remote host's transferResource() method. The remote host returns the resource piece as an array of bytes.

  4. The local host gets the data piece of the agent by invoking the remote host's transferData() method. The remote host returns the data piece as an array of bytes.

  5. The local host marks the end of the transfer by invoking the remote host's endTransfer() method. It then resurrects the agent by calling the agent's start() method.

The code

We've got the basics under our belts, so now we're ready for the code. Let's begin with a look at the Agent interface. The agent interface defines the set of methods all agents must define.

abstract public class Agent { /** * The runtime calls initialize() exactly once -- * after the agent is created. * */

abstract public void initialize();

/** * The runtime calls start() whenever an agent must be * started. * */

abstract public void start();

/** * The runtime calls stop() whenever an agent must be * stopped -- either to transfer it, to store it, or to terminate it. * * An agent whose stop() method is called should * stop all computation, store any intermediate results, join all * active threads, and promptly return. * */

abstract public void stop();

/** * The runtime calls conclude() exactly once -- before * the agent is destroyed. * */

abstract public void conclude(); }

Mobile agents should implement the Agent class and provide definitions for these four methods.

An agent host provides the environment in which agents live. The AgentHost interface defines the methods that such an environment must provide. Among them are five in support of mobility.

1 2 Page 1