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:

  1. Load the application agents when the Lime server is created.
    For instance,
    java lime.util.Launcher -load MyAgent1 MyAgent2
  2. Start the Lime server and, separately, load the application agents into it.
    In one shell, type
    java lime.util.Launcher
    This will start the Lime server with no agents running. In another shell, type
    java 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.
Some things are worth noting in the commands above:

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 InteractiveMobileAgent
loads 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 InteractiveMobileAgent
loads (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.
  1. If specified, the --mucode option must mandatorily come before the --lime option, and the --load option must be last.
  2. 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.
  3. 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.

LIME: Linda in a Mobile Environment