dimawo.agents
Class AbstractAgent

java.lang.Object
  extended by dimawo.agents.AbstractAgent
All Implemented Interfaces:
ErrorHandler, Runnable
Direct Known Subclasses:
LoggingAgent, VirtualMiddleware

public abstract class AbstractAgent
extends Object
implements Runnable, ErrorHandler

Author:
Gerard Dethier An agent is a component that handles sequentially messages submitted in an asynchronous way. The message handling code is executed by a single thread. Messages can be submitted by different threads (message submission is a thread-safe operation), including the one executing the handling code.

Agents are well suited to the design of complex parallel applications involving mostly asynchronous operations. The behavior of an application composed of agents emerges from the exchange of messages in an asynchronous way between the agents of the application. Agent based programming (ABP) can be seen as an asynchronous form of object-oriented programming (OOP): the execution of the application is based on agents (objects) exchanging messages (method calls). The main difference between the 2 approaches is that in ABP, calls are asynchronous (a call does not immediately generate a result).

This class represents an asynchronous agent template. Messages submitted to an instance of this class are inserted into a blocking queue by submitMessage. This method is protected so subclasses of AbstractAgent are able to statically (i.e. at compile time) "control" the type of the messages they accept (for example, only String objects) by defining particular submission methods (for example, submitString(String)).

An asynchronous agent can be in 3 states: init, running and stopped. Init state indicates the agent has been instantiated but has not yet been started (i.e. it does not yet handle messages, though these can already be inserted into message queue). Running state implies the agent is currently handling messages. Finally, stopped state means the agent has been stopped and no more messages are going to be handled.

The agent is in its initial state after it has been instantiated. An agent changes to running state after a call to start method. A call to start starts the thread that will execute message handling code (see run). Before any message is handled, the init method is called (this method must be defined by a subclass of AbstractAgent). After that, the message handling code extracts each message from queue and handles it according to its type (see messageHandling method).

If init throws a Throwable, the agent changes to stopped state and no message is handled. Stopped state can also be reached if the handling of a message causes a Throwable to be thrown. Finally, a call to stop inserts a special message into queue. The handling of this message causes the agent to move to stopped state. This implies that the effect of a call to stop is not immediate.

As soon as an AbstractAgent reaches stopped state, exit method is executed and after that, the thread executing the message handling code finishes its execution.

When stopped state was reached because a Throwable was thrown by either init or messageHandling, the error is forwarded to an ErrorHandler, if any was set, before exit is called.

An AbstractAgent is also an ErrorHandler: signalChildError inserts a message into queue. A default behaviour for this message handling is implemented by handleChildException(UncaughtThrowable). Of course, This method can be overriden.

Finally, an AbstractAgent has a particular logging interface: by default, all messages printed using agentPrintMessage(int, String) or agentPrintMessage(Throwable) are printed onto standard output (System.out). However, agent's logging stream can be changed by setPrintStream.

A name can be associated to an agent, this name is used by logging and is used to name the thread running the message handling code.


Nested Class Summary
static class AbstractAgent.AgentState
          Represents the 3 possible states of an AbstractAgent
 
Field Summary
protected  String agentName
          The name of the agent (used for logging and thread name).
protected  ErrorHandler errorHandler
          Error handler associated to this agent.
 
Constructor Summary
AbstractAgent()
          Instantiates an AbstractAgent without error handler and name.
AbstractAgent(ErrorHandler parent, String name)
          Instantiates an AbstractAgent having given error handler and name.
AbstractAgent(ErrorHandler parent, String name, boolean daemon)
          Instantiates an AbstractAgent having given error handler and name.
AbstractAgent(ErrorHandler parent, String name, boolean daemon, int capacity)
          Instantiates an AbstractAgent having given error handler and name.
AbstractAgent(ErrorHandler parent, String name, int capacity)
          Instantiates an AbstractAgent having given error handler and name.
 
Method Summary
 void agentPrintMessage(int verbLevel, String message)
          Logs a message on standard output if given verbosity level is high enough.
 void agentPrintMessage(String message)
          Logs a message on standard output if current verbosity level is lesser or equal to 0.
 void agentPrintMessage(Throwable e)
          Logs the stack trace of given Throwable instance on standard output.
protected abstract  void exit()
          Implements the operations to be executed when agent enters STOPPED state.
protected  LinkedList<Object> flushPendingMessages()
          Lists messages from messages queue and clears it.
static int getDefaultVerbosityLevel()
          Returns the default verbosity level of agents.
 AbstractAgent.AgentState getState()
          Provides the current state of the agent.
 int getVerbosityLevel()
          Returns the verbosity level of this agent.
protected  void handleChildException(UncaughtThrowable o)
          Handles an error event taken from message queue.
protected abstract  void handleMessage(Object o)
          Handles a new message taken from the queue.
protected abstract  void init()
          Implements the operations to be executed when agent enters INIT state.
 void join()
          Waits until the agent's thread is stopped.
 void join(long millis)
          Waits until the agent's thread is stopped or a time-out occurs.
 void run()
          This method implements the Runnable interface.
protected  void setAgentName(String name)
          Sets the name of this agent.
 void setDaemon(boolean on)
          Sets the daemon flag of the thread that will execute message handling code.
static void setDefaultVerbosityLevel(int verbLevel)
          Sets the default verbosity level for all agents that will be instantiated after this call.
 void setErrorHandler(ErrorHandler err)
          Sets the ErrorHandler associated to this agent.
protected  void setPrintStream(PrintStream printStream)
          Sets the default print stream this agent logs to.
 void setVerbosityLevel(int verbLevel)
          Sets the verbosity level for this agent.
 void signalChildError(Throwable t, String childName)
          Inserts an error event in message queue.
 void start()
          Starts this agent.
 void stop()
          Inserts a StopAgent event in the queue of this agent.
protected  void submitError(Throwable t)
          Inserts a Throwable into message queue.
protected  void submitMessage(Object o)
          Queues a message in messages queue.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

agentName

protected String agentName
The name of the agent (used for logging and thread name).


errorHandler

protected ErrorHandler errorHandler
Error handler associated to this agent.

Constructor Detail

AbstractAgent

public AbstractAgent()
Instantiates an AbstractAgent without error handler and name. The message handling thread is not a daemon and the capacity of message queue is not limited. This constructor is equivalent to AbstractAgent(ErrorHandler, String) constructor called with the 2 arguments having null as value.


AbstractAgent

public AbstractAgent(ErrorHandler parent,
                     String name)
Instantiates an AbstractAgent having given error handler and name. The message handling thread is not a daemon and the capacity of message queue is not limited. This constructor is equivalent to AbstractAgent(ErrorHandler, String, boolean) constructor called with AbstractAgent(parent, name, false).

Parameters:
parent - The error handler to associate to this agent.
name - The name to associate to this agent.
See Also:
ErrorHandler

AbstractAgent

public AbstractAgent(ErrorHandler parent,
                     String name,
                     boolean daemon)
Instantiates an AbstractAgent having given error handler and name. The capacity of message queue is not limited. This constructor is equivalent to AbstractAgent(ErrorHandler, String, boolean, int) constructor called with AbstractAgent(parent, name, daemon, 0).

Parameters:
parent - The ErrorHandler to associate to this agent.
name - The name to associate to this agent.
daemon - Daemon flag for the thread that will execute message handling code.
See Also:
ErrorHandler

AbstractAgent

public AbstractAgent(ErrorHandler parent,
                     String name,
                     int capacity)
Instantiates an AbstractAgent having given error handler and name. The message handling thread is not a daemon. This constructor is equivalent to AbstractAgent(ErrorHandler, String, boolean, int) constructor called with AbstractAgent(parent, name, false, capacity).

Parameters:
parent - The ErrorHandler to associate to this agent.
name - The name to associate to this agent.
capacity - The capacity of the incoming messages queue (see submitMessage).
See Also:
ErrorHandler

AbstractAgent

public AbstractAgent(ErrorHandler parent,
                     String name,
                     boolean daemon,
                     int capacity)
Instantiates an AbstractAgent having given error handler and name.

Parameters:
parent - The ErrorHandler to associate to this agent.
name - The name to associate to this agent.
daemon - Daemon flag for the thread that will execute message handling code.
capacity - The capacity of the incoming messages queue (see submitMessage).
See Also:
ErrorHandler
Method Detail

setErrorHandler

public void setErrorHandler(ErrorHandler err)
Sets the ErrorHandler associated to this agent. This method must be called before the agent is started (i.e. before a call to start() start).

Parameters:
err - The ErrorHandler.
See Also:
ErrorHandler

setDaemon

public void setDaemon(boolean on)
Sets the daemon flag of the thread that will execute message handling code. This method must be called before the agent is started (i.e. before a call to start()).

Parameters:
on - Value of the daemon flag.
See Also:
Thread.setDaemon(boolean)

setDefaultVerbosityLevel

public static void setDefaultVerbosityLevel(int verbLevel)
Sets the default verbosity level for all agents that will be instantiated after this call.

Parameters:
verbLevel - A verbosity level (see agentPrintMessage(int, String) agentPrintMessage).

getDefaultVerbosityLevel

public static int getDefaultVerbosityLevel()
Returns the default verbosity level of agents.

Returns:
The default verbosity level of agents.

setVerbosityLevel

public void setVerbosityLevel(int verbLevel)
Sets the verbosity level for this agent.

Parameters:
verbLevel - A verbosity level (see agentPrintMessage(int, String) agentPrintMessage).

getVerbosityLevel

public int getVerbosityLevel()
Returns the verbosity level of this agent.

Returns:
The verbosity level of this agent.

stop

public void stop()
          throws InterruptedException,
                 AgentException
Inserts a StopAgent event in the queue of this agent. If this method is called multiple times, only the first call will have an effect. The following calls will be ignored. This method ensures that the agent thread is interrupted only once.

Throws:
InterruptedException - If the agent thread was interrupted.
AgentException - If the agent is already stopped.

start

public void start()
           throws AgentException
Starts this agent. If no thread is attached to this agent or the agent was already stopped, this method will have no effect.

Throws:
AgentException - If the agent was already started.

getState

public AbstractAgent.AgentState getState()
Provides the current state of the agent. This method allows the thread-safe access to the state of the agent.

Returns:
The current state of the agent.

join

public void join()
          throws InterruptedException
Waits until the agent's thread is stopped. If the agent was not already started, this method will have no effect.

Throws:
InterruptedException - if this thread is interrupted.
AgentException

join

public void join(long millis)
          throws InterruptedException
Waits until the agent's thread is stopped or a time-out occurs. If the agent was not already started, this method will have no effect.

Parameters:
millis - The duration of the time-out given in milliseconds.
Throws:
InterruptedException - if this thread is interrupted.

run

public void run()
This method implements the Runnable interface. It describes the sequential code executed by message handling thread:
  1. initialization,
  2. message handling loop,
  3. termination (caused by a stop event or an error).

Specified by:
run in interface Runnable

signalChildError

public void signalChildError(Throwable t,
                             String childName)
Inserts an error event in message queue. This method is generally called by child agents i.e. agents instantiated by this agent.

Specified by:
signalChildError in interface ErrorHandler
Parameters:
t - The error.
childName - A name describing the error's source i.e. the component that caused the error.

submitMessage

protected void submitMessage(Object o)
                      throws InterruptedException
Queues a message in messages queue. The call can be blocking if the messages queue of the agent is full.

Parameters:
o - The message to insert into the queue.
Throws:
InterruptedException - If the call is blocking and executing thread is interrupted.

handleChildException

protected void handleChildException(UncaughtThrowable o)
                             throws AgentException
Handles an error event taken from message queue.

Parameters:
o - The error.
Throws:
AgentException - If the agent does not have an error handler.

agentPrintMessage

public void agentPrintMessage(int verbLevel,
                              String message)
Logs a message on standard output if given verbosity level is high enough. The message is printed only if given verbosity level is greater or equal to current verbosity level.

Parameters:
verbLevel - Message's verbosity level
message - The message to log.
See Also:
setVerbosityLevel(int)

agentPrintMessage

public void agentPrintMessage(String message)
Logs a message on standard output if current verbosity level is lesser or equal to 0.

Parameters:
message - The message to log.
See Also:
setVerbosityLevel(int)

agentPrintMessage

public void agentPrintMessage(Throwable e)
Logs the stack trace of given Throwable instance on standard output.

Parameters:
e - The given Throwable instance.

flushPendingMessages

protected LinkedList<Object> flushPendingMessages()
Lists messages from messages queue and clears it. This allows an agent to handle the messages still present in its message queue when it terminates its execution (i.e. arrives in STOPPED state).

Returns:
The list of messages from message queue.

setPrintStream

protected void setPrintStream(PrintStream printStream)
Sets the default print stream this agent logs to. The access to the print stream is not thread-safe.

Parameters:
printStream - A print stream.

setAgentName

protected void setAgentName(String name)
Sets the name of this agent.

Parameters:
name - The name of the agent.

submitError

protected void submitError(Throwable t)
Inserts a Throwable into message queue. When the Throwable is taken from queue, it is thrown and causes therefore the agent to terminate its execution.

Parameters:
t - The Throwable.
See Also:
messageHandling(), run()

init

protected abstract void init()
                      throws Throwable
Implements the operations to be executed when agent enters INIT state.

Throws:
Throwable - If an error occurred during initialization.

handleMessage

protected abstract void handleMessage(Object o)
                               throws Throwable
Handles a new message taken from the queue.

Parameters:
o - A message.
Throws:
Throwable - If an error occurred during message handling.

exit

protected abstract void exit()
Implements the operations to be executed when agent enters STOPPED state. The agent enters this state because a stop event was taken from queue or an error occurred. The 2 situations can be differentiated by checking agent's state.



Copyright © 2011 DiMaWo Team. All Rights Reserved.