mechanism. Inter-agent communication is possible
through not only blocking but also non-blocking and
polling mechanisms. An agent can send messages to
other agents in three different ways that are through
tell, tellAndWait and tellAndPoll message passing
methods. An agent can tell a message and proceed
with its current behavior. An agent can also
tellAndWait a message and block for its reply before
advancing. The third approach is to tellAndPoll a
message and iteratively check for the reply. This
approach called polling allows for situations when a
behavior should be sustained while a message reply
is also waited for. These approaches are
syntactically specified as in Code Snippet 2, Code
Snippet 3 and Code Snippet 4.
An agent may receive messages of different class
types. The perceive block for a definite message
class is where every received message that is an
instance of that class is directed to. Every agent has
a hidden thread-safe message queue. All the
messages that other agents send to the agent are put
into its message queue. When an agent specification
is compiled, a hidden message dispatching behavior
is added to the agent behaviors. The message
dispatching behavior continuously iterates the
message queue, identifies the type of each message
and runs the perceive block of the identified
message type with the message as the parameter. All
the message queuing and runtime type identification
issues are handled behind the scene by the code that
is generated and inserted by the compiler into the
user code and in part by classes of Aria core
package. As all the perceive blocks of an agent are
executed sequentially in a single thread, a perceive
block can only contain a short processing on the
message. For instance it can contain the action that a
simple reflex agent performs in realizing a message
of a definite type. This is most common for user
interface agents. As most of the messages they
receive are requests for presentation and such
requests can be carried out rapidly, user interface
agents are usually reflex agents.
Behaviors are where the agent’s processing
should be coded. The code snippet of a behavior is
translated to a repeatedly running code. Every
behavior is executed on a separate thread by default
and this supports concurrent behaviors in an agent.
Processing needed to reply some message types
may be time consuming and messages of such types
can not be promptly answered. As perceive blocks
should only contain short processing tasks, there is a
need that messages of time consuming types be
directed to a behavior to be further processed. This
could be coded in Aria as coded in Code Snippet 5.
To support the user to accomplish this much easier,
Aria allows defining message processing behaviors.
A behavior can declare to process a definite message
type and the presented code is automatically
generated by the compiler. This means that Code
Snippet 6 has exactly the same effect as Code
Snippet 5.
A message that is being processed either in a
perceive or behavior block can be replied by the
reply keyword as shown in Code Snippet 7. When a
message is replied, if the sender is waiting for the
reply, the sender unblocks and gets the reply
message as the return value of tellAndWait method.
But if the sender is not waiting for the reply, the
reply is simply sent to it to be queued and processed
later. Reply statements without an explicit message
are usually used to unblock sender agents that are
waiting for a task to be finished. All the needed
synchronizations are handled by Aria core package.
An agent is created and made alive as shown in
Code Snippet 9. Agent’s (hidden) message
dispatching behavior and all the behaviors in the
agent definition are started when the agent is
commanded to become live. The atBirth block is
executed when the agent is becoming live just before
any of the behaviors are started. An agent can be
requested to terminate by telling it a message of
TerminateRequestMessage class. When a message
of TerminateRequestMessage class is received, the
agent dies by default by terminating all its behaviors
and executing the atDeath block when all the
behaviors are terminated. This default reaction to
TerminateRequestMessage can also be overridden
easily by providing a perceive block for it.
Agent definitions support all the constructs that
can be defined inside class definitions. Fields can be
defined for agent information storage. As fields are
accessible from all the perceive and behavior blocks
and agent behaviors can execute concurrently, care
should be taken for synchronizing field access.
Methods can also be defined for an agent but rarely
an agent’s method has a public access. Composition
serves as a way to reuse existing agents and built
more high-level agents with greater capabilities from
them. An agent can obviously be composed of other
agents. Each subagent can be capable of performing
a part of the agent’s responsibilities. The agent itself
can act as a manager or coordinator.
3.2 Inheritance and Polymorphism
Aria agent specification supports inheritance in both
agent specialization and service provision.
ICSOFT 2008 - International Conference on Software and Data Technologies
80