On this page:

Introduction 

Actions are deferred tasks that an agent can submit to its parent, which will be executed on the agent itself (e.g., migration, cloning, death) or on some another selected agent (e.g. change in the quantity of the resource). It is recommended that any structural change in the agents tree be made using such actions. Actions are available only to light agents. They are carried out in two stages:

  • during the computation, an agent submits an action to its parent (e.g., the agent decides to die, leading to its removal from the computation structure),
  • The parent agent processes a queue and performs all the submitted actions (e.g., actually removes the agent).

The ability to perform actions is available through the agent environment. This means that an agent can submit actions to its parent, who is also his environment. The default built-in actions are:

  • add a new agent
  • transfer an agent to another environment 
  • remove an existing agent

In addition to that, users are able to define their own actions.

There are two kind of actions available in AgE:

  • Simple actions are responsible for the execution of an individual tasks on a single agent (e.g., agent death, migration). A single action contains the address of the agent on which it is to be performed, and the context of the action. The action context encapsulates all the additional information needed to perform an action (e.g., the amount of resources to be transferred between agents). The action context is dependent on the kind of action it describes.
  • Complex actions group together some other actions, according to the Composite design pattern.

Action phases

Each action is executed in three phases:

  • INIT - initialization and validation of addresses. In this phase, beyond the validation of addresses, there can be some additional activities, such as adding a new agent. Thanks to that the next actions can be performed on such a newly added agent.
  • MAIN - the main stage of action execution
  • FINISH - action finalization - this phase may include additional activities carried out at the end of the action. In this phase, for example, agents can be removed from the environment - this makes sure that the agent is not removed during the main action stage, when other agents can refer to it.

In the case of complex actions, the first phase is performed on all simple actions, then the next phase is again performed on all simple actions, etc.

Actions executed by aggregates

/**
 * Executes INIT action phase
 *
 * @param action
 *            action to perform
 * @return collection of agent addresses which are used by action "actionName"
 */
@AgentAction(name = "actionName", phase = ActionPhase.INIT)
protected Collection<IAgentAdddress> performInitActionName(SingleAction action) {
	// ...

}
/**
 * Executes MAIN action phase
 *
 * @param target
 *            agent on which action will be performed
 * @param context
 *            action context
 */
@AgentAction(name = "actionName", phase = ActionPhase.MAIN)
protected void performInitActionName(IAgent target, IActionContext context) {
	// ...

}
/**
 * Executes FINISH action phase
 *
 * @param target
 *            agent on which action will be performed
 * @param context
 *            action context
 */
@AgentAction(name = "actionName", phase = ActionPhase.FINISH)
protected void performFinishActionName(IAgent target, IActionContext context);
	// ...
}

Actions executed by strategies

Actions can be realized by external strategies and it's realization is independent from aggregate implementation.

Note

Actions realized by strategies should be used by default. They can't be used only when implementation of an action needs access to internal aggregate attributes or operations.

To define actions executed by strategies follow the steps:

  1. Define an action context with a specified id (let's say sampleAction).
  2. Add implementation of the action by providing a class which implements IPerformActionStrategy - see API for more details.
  3. Register the action implementation in configuration file by name given in action context:

    <strategy name="sampleAction" class="org.jage.examples.actions.SampleActionStrategy" />
    

Defining action context

Action context is a class which describes an action execution context and has two roles:

  • defines action id,
  • contains required data to perform an action.

The following snippet presents a sample action context which allows for getting:

@AgentActionContext("sendMessage")
public class SendMessageActionContext implements IActionContext {

    private final IMessage<IAgentAddress, ?> message;

    public SendMessageActionContext(final IMessage<IAgentAddress, ?> message) {
        this.message = checkNotNull(message);
    }

    public IMessage<IAgentAddress, ?> getMessage() {
        return message;
    }
}
  1. The context must be annotated by @AgentActionContext with a name of the action (see API for more details). The name is resolved during action execution depending on action type (realized by strategy or aggregate method).
  2. The class must implement IActionContext.
  3. If required, the class should define attributes needed during action execution. In example, the context contains a message to send.

How does an agent create an action?

To perform an action, an agent needs to call the doAction method, inherited from AbstractAgent, with the following parameters:

  • an address selector which specifies the target agent(s), on which the action is to be executed,
  • an action context which specifies the action to be executed and contains required data (if needed).

The following snippet presents the creation of a sample action, which will be executed on the agent itself:

@Override
public void step() {
	doAction(onSelf(new SampleActionContext()));
	// ...
}

Samples

Sample project which illustrates the action mechanism can be found in examples solutions and applications (https://age.iisg.agh.edu.pl/svn/trunk/examples/) in org.jage.examples.actions package.