Starting the Runtime
The Lime server embodies the runtime support needed to run applications on a
given host. It is possible to run multiple Lime servers on each host, as long
as they are started on different ports. This is useful for testing
applications where eventually multiple hosts will be used, but during testing
the hosts are simulated. The Lime server can be started from within a Java
application, or from the command line using the lime.util.Launcher
.
If the Lime server is started from within a Java application, it runs as a
separate thread within the Java VM that contains the application. Please refer
to the API documentation for lime.LimeServer
for a description of
the methods available on a LimeServer
object.
If the Lime server is launched from the command line, it is executed within a separate Java VM. Since the actual computation is performed by agents executing in a Lime server, the problem remains of loading such agents into the Lime server. There are basically two ways to achieve this with the current API:
- Load the application agents when the Lime server is created.
For instance,java lime.util.Launcher -load MyAgent1 MyAgent2
- Start the Lime server and, separately, load the application agents into
it.
In one shell, typejava lime.util.Launcher
This will start the Lime server with no agents running. In another shell, typejava lime.util.Launcher -quit -load MyAgent1 MyAgent2
This will load the agents into an already existing Lime server (the one we previously started) and then exit immediately.
- Finding the
.class
files. The argument to the-load
option are one or more.class
files, each containing a subclass ofStationaryAgent
. (Notice how the.class
suffix is not specified in the parameters.) The bytecode for the agents must be reachable from theCLASSPATH
associated with the Lime server, otherwise an error is generated. - Using
-load
and-quit
. The-quit
options allows to use an auxiliary Lime server for the sole purpose of loading one or more agents into an already existing Lime server on the same host. Notice that the-load
option must always be the last one on the command line.
Launching Mobile Agents
The text above describe how to launch a server that can contain only
stationary, non-mobile agents. However, Lime allows also for mobile agents, and
actually an adaptation layer has
been developed that in principle allows to use Lime with any mobile agent
system. In the current distribution, the only adapter provided supports the µCode
mobile agent toolkit. Operation of this system with Lime requires a different
launcher, lime.mobileagent.mucode.Launcher
, with slightly different
command-line options:
Usage: java lime.mobileagent.mucode.Launcher [--mucode [mucode options]] [--lime [lime options]] [--load [class names of agents to be loaded]] OR java lime.mobileagent.mucode.Launcher [--send <host:port of target muserver <class names of agent to be loaded remotely>] For instance:
java lime.mobileagent.mucode.Launcher --mucode -port 2000 --lime -port 3000 -debug on --load InteractiveMobileAgentloads
InteractiveMobileAgent
in a mucode server that listens on port 2000, connected with a Lime server (whose debug messages are enabled) listening on port 3000.
java lime.mobileagent.mucode.Launcher --send localhost:2000 InteractiveMobileAgent InteractiveMobileAgentloads (remotely) two additional instances of
InteractiveMobileAgent
in the mucode server previously
created and then quits.After this last command, if the three instances of
InteractiveMobileAgent
engage their tuple
spaces they will all share the same host-level tuple space.Note:
- If specified, the
--mucode
option must mandatorily come before the--lime
option, and the--load
option must be last.
- The
--load
option causes the mobile agent to be loaded into the µcode server. The lime option-load
instead loads the agent directly in the Lime server. - The
--send
option performs the remote loading and then quits.
For additional information about the options available for the µCode server and the system in general, please see the µCode site.
Engagement/Disengagement in Lime
In a mobile environment, changes in connectivity among hosts are a normal occurrence as components move in and out of range of one another. The sets of connected hosts form dynamic communities which in Lime share their tuple spaces. The process of a host coming into range is referred to as engagement while the departure of a host is referred to as disengagement. Both engagement and disengagement are atomic. In other words, all hosts see the change of system configuration in the same order. During engagement, all misplaced tuples whose destination agent is now present are migrated that destination. On disengagement, no tuples need to be migrated because they are already co-located with the agent responsible for them.
Engagement decisions are hangled by the Group Manager package, whose
behavior can be modified by several parameters passed to Lime (see Starting the Runtime). The Group Manager uses a
MemberDetector
to determine when two hosts are connected, and a
GroupDisseminator
to maintain the current state of the group and
inform member hosts of changes. When the member hosts receive notification of
a group change, their LimeServers automatically engage. The Group Manager,
encapsulated in the groupmgmt
package, is designed to be
independent of Lime and useful for other projects. See the API documentation
for groupmgmt.GroupManager
for usage details.
The group management functionalities in Lime support Group-To-Group engagement. In previous versions of Lime, the engagement protocol supported only the addition of single members to the group at a time. This version, however, allows multiple groups to operate independently, and, when the members of the two groups satisfy the engagement requirements detailed below, the groups merge into a single group.
Lime is distributed with two MemberDetectors
: the
BeaconingDetector
multicasts periodic beacons and connects to any
server whose beacons it can "hear," and the SafeDistanceDetector
uses the same beaconing system but adds a filter to only connect to hosts
within a safe distance. One GroupDisseminator
is included: the
SinglePhaseDisseminator
informs hosts of changes to the group via
a single phase transaction (a single unicast message).
Previous versions of Lime required one host to be declared as the leader
for engagements. All host engagement is now taken care of by the Group
Manager and so all agents should engage with the normal call:
LimeSystem.engage()
.
Engagement via Beaconing
When using the BeaconingDetector
to initiate Lime engagements,
each host constantly beacons a "hello" message heard by any other
host within communication range. The received beacons are compared to
the receiving host's current state, and, if the beacon corresponds to a new
entrant into the group, an engagement is begun. This engagement is
mediated by a "leader" (not known to the application) and uses the
transaction protocol implemented by the
SinglePhaseDisseminator
. This protocol ensures the new
group information is distributed to all of the members of the new group at the
same time to guarantee atomicity of engagements.
When a group member decides to disengage, the member sends a special beacon that indicates that it is shutting down. Any other member in its group that receives this beacon passes the information along to the disseminator, which triggers a new group change, and passes new group information to all of the old group members. We refer to this process as "announced disconnection". Because periodic beaconing can be expensive (since it generates quite a bit of additional traffic in the network), the period for the beaconing is adjustable. The advantage to using a longer beaconing period is that this extra traffic decreases. The disadvantage to using longer beaconing periods is that engagement takes longer. That is, when two hosts (or groups) move within communication range of each other, it might take longer for them to discover each other, since the beaconing period is larger.
Engagement via Safe Distance
The second type of engagement mechanism provided in Lime allows hosts (or groups of hosts) to engage based on criteria that define a "safe distance". This safe distance is defined based on the communication range of the devices, their maximum velocities, and a number of other physical factors. At a high level, the safe distance is essentially defined as the physical distance between to hosts in which a communication can complete before the hosts can no longer communicate. If we allow only links meeting this requirement to support communication in Lime, we can ensure that any communication Lime starts will complete before the participating parties disconnect.
When using safe distance based engagement in Lime, the group members still
beacon information that includes their current physical location. This
information is used by the SafeDistanceDetector
class to
ensure that only links that satisfy the safe distance requirements are
included in the logical network. If a host is discovered to have moved
within safe distance, the group member discovering the new host (or group)
notifies its SinglePhaseDisseminator,
which initiates an
engagement protocol. Likewise, if a current member of the group has
moved out of safe distance, a disengagement protocol is initiated.
Support of the safe distance engagement relies on the ability of the group
member to have information about its current physical location. The
location
package included with the groupmgmt
package
provides two mechanisms for gathering this information. The first,
RealGPSMonitor
interfaces with a physical GPS device, collects
information from the device, and provides it to the application. The
second, FakeGPSMonitor
interfaces with the application's
user, displaying a GUI through which the user can manipulate the device's
"location". This allows testing of location based applications
without having to physically move the devices.