Making Agents Mobile

This is not intended to be a serious attempt to implement mobile agents, but is a quick sketch of how it could be done quickly in ASTRA…

The code below uses the UDP Communication Channel provided with ASTRA to implement a very simple form of agent migration (only belief state is migrated). The solution is based on the idea of having a platform manager that is able to serialise the agent state, transmit it, and then reconstruct the state on the destination platform:

  agent MigrationManager {
      module System system;
      
      rule @message(request, string sender, incoming(object<astra.lang.AgentState> state)) {
          try {
              system.reconstruct(state);
              send(inform, system.getNameFromState(state), migrated());
          } recover {
              send(failure, sender, incoming(state));
          }
      }

      rule @message(request, string sender, migrate(string target)) {
          object<astra.lang.AgentState> state = system.deconstruct(sender);
          send(confirm, sender, migrating(target));
        	
          when (~system.agentExists(sender)) {
              send(request, target, incoming(state));
          }
      }
      
      rule @message(failure, string sender, incoming(object<astra.lang.AgentState> state)) {
          system.reconstruct(state);
          send(failure, system.getNameFromState(state), migrate(sender));
      }
  }

The first rule deals with an incoming (migrating) agent. The incoming agents state is received as part of the message, and the agent uses this state to reconstruct the agent on the new platform. If the reconstruct(…) action fails, then the agent indicates this by sending a message back to the source migration manager. This reply is handled by the third rule, which recreates the agent locally and indicates failure of the migration attempt.

The second rule is the rule that triggers a migration attempt. When the Migration Manager receives a request from an agent to migrate, it captures the agents state, confirms that the migration will occur, and then waits for the agent to terminate itself (it must work this way because on an agent can only self terminate or be terminated by its owner – the agent that created it). Once the agent it terminated, the Migration Manager detects this and sends the state over to the target platform.

To illustrate this, we will create a simple mobile agent:

  agent Flighty {
      module System system;
      module Console console;
      
      rule rule +!main(list args) {
          send(request, "m1", migrate("m2"));
      }

      rule @message(confirm, string sender, migrating(string target)) {
          system.terminate();
      }

      rule @message(inform, string sender, migrated()) {
          console.println("I'm ALIVE!!! and I'm on " + sender);
      }
  }

When created, this agent sends a message immediately to Migration Manager “m1” requesting to migrate to “m2”. Once it gets confirmation, the agent terminates itself. When migration is complete, the agent is informed of the completion of migration by the destination Migration Manager, and it prints out a message.

Finally, we need to set up the source and target platforms. The target platform code is:

  agent Test2 {
      module System system;
      module Messaging M;

      rule +!main(list args) {
          M.installService("udp", "astra.messaging.UDPMQService");
          M.startService("udp");
  
          system.createAgent("m2", "examples.MigrationManager");
      }
  }

This agent simply sets up the UDP Message Service and creates a Migration Manager. The source platform code is similar, except that it must also create our Flighty agent:

  agent Test {
      module System system;
      module Console console;
      module Messaging M;

      rule +!main(list args) {
          M.installService("udp", "astra.messaging.UDPMQService");
          M.startService("udp");
  
          system.createAgent("m1", "examples.MigrationManager");
  
          system.createAgent("flighty", "examples.Flighty");
          send(inform, "flighty", action("go"));
      }
  }

To test this, simply write the four agent classes using the Eclipse plug in and then run them in the order: Test2 followed by Test. Flighty will automatically migrate from Test’s platform to Test2’s platform. :o)