Armed with the structural knowledge taken from the docs section, we will now have a little Q&A on how to program with the Agentopia framework. You will see some UML here too; this time, it is sequence diagrams to illustrate how the command flow is.
Q: How do I start a host with a market place?
Have an open port ready (on Linux, probably something greater than 1024 unless you are root), and run the following source code:
final int port = 15907; Host host = new Host(port); host.start();
This will open a server socket on port 15907, and create an
IMarketPlace
automatically, which ticks with a refresh
rate of 3 seconds.
If you want to control the refresh rate yourself, use the
new Host(port, false)
constructor to create a market
place without timer.
The following UML sequence diagram shows what happens as a cause of the the source code above.
Upon start()
, which starts a new thread,
the Host
only calls start()
on the
market place also if the automatic start flag is set;
otherwise, you would need to manually call runStartup()
,
then repeatedly runTick()
, and finally
runShutdown()
on the IMarketPlace
by yourself.
Q: What if I have several network cards (and thus several IP addresses) on my host?
You need to decide which IP or hostname to use. And then you need to tell the host:
final HostId hostId = new HostId("myhostname.com:15907"); Host host = new Host(hostId.getPort()); host.setHomeId(hostId); host.start();
I agree that it would be better if the network card would not matter. The host itself actually does not care, because it just opens a socket on a port, available from wherever. The agents, on the other hand, have to know the home host to which they jump back (on a remote host, saying "jump me to 127.0.0.1" does not have much effect).
Q: How do I add exits and serviteurs?
To create sustained connections to another Host
,
you designate a HostId
with a hostname or IP and a port.
Using this host id, you call createExit()
on the market
place, which in turn creates a new Sustainer
,
as shown in the UML diagram below.
Creating a serviteur involves instantiating one and adding it
to the market place.
If the serviteur also implements the IAgentopiaServerRunnable
interface, a thread is started on it.
This is useful e.g. for regular checks on the file system.
Q: How do I start an agent?
Depends on the agent; here a remote walker agent is started.
IAgentopiaAgent agent = new RemoteWalkerAgent(); host.jumpStart(agent);
Jumpstarting an agent opens a client socket (via a Communicator
)
to the local Agentopia
instance (e.g. "localhost:15907").
The serialized agent (plus subobjects) as well as its class bytecode
are loaded into the market place, as shown in the following UML diagram.
On the server socket side, the host tasks a
ConnectionInputHandler
with processing the transmitted
agent, finally adding it to the market place.
The de-serialization and dynamic classloading means that from now on,
the agent has very limited access rights (no file I/O, no networking)
on the host.
To exchange stuff, use the treasuring functions on the market place.
Q: How do I actually write my own agent?
Quite easy from the structure, more complex in intent.
With the default Agentopia
implementation, you need to subclass AbstractAgent
and implement two methods: runActivity()
and
runResults()
.
Consider the following UML sequence diagram:
With a tick of the market place, an AgentExecutionThread
runs the agent after supplying a logger and the current market place.
The run()
method checks the agent state and calls either
runActivity()
as default, or runResults()
when arriving back home after the mission has been finished.
During the activity run, you will mostly use methods in the
AbstractAgent
superclass; call goExit()
to wander
to another host, runService()
to invoke a serviteur service,
and finally goHome()
to automatically transfer back home.
In the results run, you will want to bury any results on the
home market place by using the buryTreasure()
method.
Using its heightened access to the market place, your client class
can then invoke retrieveTreasureAsHost()
on the market
(during burying, an MD5 hash of the agent bytecode is taken,
and only agents with matching bytecode can retrieve it;
as a host, the same restriction does not apply).
Q: Do I have to subclass AbstractAgent
?
As long as you plan to use the MarketPlace
implementation
delivered with Agentopia, the answer is yes.
To exchange the market place, subclass Host
and override the
createMarketPlace()
method to return your implementation instead.
Keep in mind that only classes annotated by AgentopiaAgentMarker
transmit their class bytecode alongside the serialized object when
going through a Sustainer
;
therefore, a superclass would need to have this marker too.
Your agent still needs to implement the IAgentopiaAgent
interface in all cases.
Q: How do I shutdown the system?
Just call shutdown()
on the host and wait until all threads
have finished (a few seconds should suffice).
The UML sequence diagram below shows the shutdown process.
Everything is shut down in a chain reaction.
Even agents are expected to react
to shutdown()
calls by regularly checking whether
this method has been called.
Q: Bonus question: How does the Agent GUI work for a specific agent?
The classic MVC (model-view-controller) pattern is followed.
There is an AgentopiaSwingController
,
which creates agents and agent GUIs
(defined using the AgentopiaAgentWithGUI
annotation
on the agent class) on behalf of the application GUI,
as shown in the UML sequence diagram below.
In the case above, the AgentStarterPanel
creates
a TransporterAgent
and the accompanying
TransporterAgentGui
.
In the processAgentCreated()
method, the agent GUI
has the chance to set its appearance before being shown in an
AgentInternalFrame
within the application GUI.
The agent GUI should supply some sort of "Start" button,
which initializes the agent with an init(...)
method before jump starting it.
Upon returning, an event is fired at the controller,
reaching the agent starter panel, which then retrieves or re-creates
the agent GUI and calls processAgentReturned()
.
After retrieving the agent result treasure from the market
place, the agent GUI should then supply some sort of "Save" button,
which allows saving the results to the local file system.
Q: Any further questions?
This little Agentopia Q&A might have answered the most basic questions, but many more remain open. Over in the author section, you can contact me in case you have a specific question that is not in the list above.