Usage Guideline for the DistView Toolkit

Introduction: DVSharedState

The DistView toolkit provides support for group-based inter-process communication and sharing application objects.  In DistView, application processes communicate with each other by exchanging messages.  The communication is group-based.  A process broadcasts a message to a group in order to send the message to other processes.  In order to receive a message broadcast to a group, a process should have joined the group.

A DistView component, called DVSharedState, provides group communication facilities.  It interfaces between Corona, a group communication subsystem, and a DistView-based application.  A DVSharedState provides interface for creating/joining a group and broadcasting messages.  An application creates a DVSharedState for each group it creates/joins.

The DVSharedState also supports sharing of application objects.  The DVSharedState allows an application process to export one or more objects to its group.  When another process joins the group, its DVSharedState imports the exported objects, i.e., newly instantiates the objects within the importing process and initialize with current state.   The exported and imported objects synchronize their state by broadcasting state updates.

This guideline does not describe all the features of the DistView toolkit.  Instead, its goal is to highlight the basic facilities of the current Java implementation of the toolkit and illustrate the toolkit's usage in the development of an example Java application, called DVChatTest.

DVSharedState Basics

A DVSharedState is a DistView component that interfaces between Corona and a DistView-based application.  The application should create an instance of DVSharedState for each group it creates/joins as in:

    DVSharedState myGroup = new DVSharedState(groupName);,

where groupName is the name of the group to join.  Once a DVSharedState is created, the application should provide information about its runtime environment as in:

    myGroup.setUp(coronaHost, coronaPort, userName, userHost);,

where coronaHost is the name of the host machine on which Corona is running, coronaPort is the number of the port to which Corona is listening for connection requests, userName is the application-defined name for the end user, and userHost is the name of the end user's host machine.  The userName and userHost parameters are used for awareness purposes, e.g., when the user joins a group, the existing users of the group are notified of the new member with the userName and userHost information.  For proper operation, the application should invoke setUp() prior to connecting and/or joining a group.

In order to connect to Corona, the application should invoke the connect() method as in:

    myGroup.connect();

Once successfully connected, i.e., connect() returns 1, the application is now connected to Corona but has not yet joined its group.  The application can still query Corona for the names of existing groups, broadcast messages to existing groups, get notified of creation and deletion of groups etc.  The application disconnects from Corona by invoking disconnect().

In order to join a group, the application should do:

    myGroup.join();

At the successful completion of the join() call, i.e., join() returns 1, the application is transferred the current state of the group.  Invoking join()automatically connects the application to Corona.

The application leaves its group by invoking the leave() method on the DVSharedState.  Invoking leave() automatically disconnects the application from Corona.
 

Example 1: DVChatTest

To illustrate the usage of the DistView toolkit, we have developed an application, called DVChatTest.  The DVChatTest allows users to exchange textual messages.  The following figure shows the graphical user interface of DVChatTest.
In order to send a message, the user types in the message in the top textfield and clicks the "Send" button.  The message is broadcast to a group that the DVChatTest joins upon start-up (the name of the group, the host on which Corona is running, and the port to which Corona is listening are command-line parameters).  The message is then received by the existing members of the group.  The received message is displayed in the bottom textfield.

In order to run the DVChatTest application, enter in the following at the prompt:

    java DVChatTest coronaHost coronaPort groupName,

where the arguments are as explained earlier.  Note that this applicatoin does not utilize the user name or user host information.  The user should be in the directory that contains the DVChatTest class and should have set the CLASSPATH environment variable to contain the DistView packages.

DVChatTest: Architectural Overview

The following figure shows the architectural overview of DVChatTest:
In order to separate the DVChatTest's application functionality from its user interface, the DVChatTest code consists of the three files: DVChatTestFrame.java, DVChatTestListener.java, and DVChatTest.java.  The  DVChatTestFrame.java  contains user interface code,  DVChatTestListener.java  has code for notifying the user action on the interface, i.e., clicking on the "Send" button, to the DVChatTest, and DVChatTest.java contains code for message exchange mechanism.  When the user clicks on the "Send" button, the DVChatTestFrame sends a sendMessage() message to a DVChatTest object, which is a DVChatListener to the DVChatTestFrame.  The sendMessage() passes the user's textual message to the DVChatTest as a String parameter.  Upon receiving a broadcast message, the DVChatTest sends a displayMessage() message to the DVChatTestFrame, passing in the broadcast message as a String parameter.

DVChatTest.java has two versions, depending on how the message exchange mechanism is realized.  In the first version, the DVChatTest uses the DistView's message broadcasting facilities.  In the second version, it employs the toolkit's dynamic object sharing facilities.

DVChatTest: Message Broadcasting

In this version, a group of DVChatTest processes communicate with each other by broadcasting messages.  In DistView, broadcasting a message consists of two tasks: sending to and receiving from Corona.  An application sends a message by invoking the bcast() method on a DVSharedState.  In the processing of bcast(), the DVSharedState sends the message to Corona, which broadcasts the message to the members of the target group.  The DVSharedState supports intra-group communication by allowing the sender application to specify the name of a target group in Corona.

The message broadcast by Corona is received by a DVSharedState of a target group member, i.e., the DVSharedState that the target group member is using to interface with Corona.   Upon receiving the message, the DVSharedState should notify the application so that the application can process the message.  To this end, the DistView toolkit defines a class, called DVBcastHandler.  The DVBcastHandler defines an method, called procBcastMsg(), which the DVSharedState invokes upon receiving a broadcast message from Corona.  The application creates a subclass of DVBcastHandler, in which it overrides the procBcastMsg() method for application-specific processing of broadcast messages.  The application then registers an instance of its broadcast handler with the DVSharedState as in:

    ...
    DVSharedState myGroup = new DVSharedState(groupName);
    ...
    myGroup.setBcastHandler(myBcastHandler);
    ...

The application can set the broadcast handler for the DVSharedState at any time.  If the DVSharedState does not find a broadcast handler when receiving a message, it simply ignores the message.

In DVChatTest, the broadcast message handling is performed by an instance of DVChatTestHandler, which inherits from DVBcastHandler.  In its procBcastMsg(), the DVChatTestHanlder invokes the displayMessage() on the DVChatTestFrame, passing in the String extracted from the received message.  The following figure graphically illustrates the broadcast message handling process in DistView.  The source code for this DVChatTest is found in this version of  DVChatTest.java .

DVChatTest: Object Sharing via Exporting/Importing

In this version, a group of DVChatTest processes communicate with each other by sharing an object.  Specifically, they share a DVStringBuffer object, the DistView version of the Java's StringBuffer.  In DistView, object sharing is based on an export/import paradigm, and shared objects are replicated in an importing process at runtime.  In order to share an object, a process first exports the object in a group to which it belongs.  The exported object becomes part of the group's state.  In order to import the object, a process should join the group.  Upon join, the process is transferred the object's current state as well as the object's type information.  The object is newly instantiated within the new process and initialized to its current state.  The object exporting and importing is handled by the DVSharedState in conjunction with the Corona communication subsystem.

In order to export an object, the exporting process invokes the add() method of the DVSharedState, as in:

    ...
    DVSharedState myGroup = new DVSharedState(groupName);
    myGroup.setUp(coronaHost, coronaPort, userName, userPort);
    ...
    myGroup.add(aSharedObj);
    ...
    myGroup.join();,
    ...

where aSharedObj is the object to be exported.  In this release of DistView, all the add() method invocations should be made prior to the join() method invocation; any add() method invocation subsequent to the join() call have no effects.  After the successful join() call, aSharedObj is considered exported and is part of the state of the group of groupName.  The add() method may be invoked as many times as needed.  aSharedObj may also be an application window, i.e., a Java frame, in which case all the components "contained" in the window and their immediate "listener" objects are shared.  For brevity, we do not consider in this guideline when aSharedObj is a window.

aSharedObj should be an instance of a direct or indirect subclass of DVObject.  The DistView toolkit provides a library of such classes, including DVStringBuffer.  The instances of DVObjects are group-aware, in the sense that they can automatically detect when they are being used for group work and broadcast their state updates to a group in Corona, for which they are being shared.  Each DVObject has predefined interface through which their internal state is changed.  For example, the String value of a DVStringBuffer may be changed via its setStrBufValue() method.  When the state of a DVObject changes, it broadcasts its state update via DVSharedState's bcastStateUpdate() or bcastStateChange() methods as in:

    ...
    DVSharedState myGroup = new DVSharedState(groupName);
    ...
    myGroup.join();
    ...
    myGroup.bcastStateUpdate(aSharedObj, stateUpdateMsg);
            or
    myGroup,bcastStateChange(aSharedObj, stateUpdateMsg);,

where stateUpdateMsg is a message containing the state update information on aSharedObj.  The bcastStateUpdate() method is  used to broadcast an incremental state update information, whereas the bcastStateChange() method is used to broadcast the new state of aSharedObj.  The invocation of either the bcastStateChange() or bcastStateUpdate() method in a DVObject is automatically performed when its state is updated via its state update interface.

As stated earlier, a shared object is locally replicated when a process joins a group.  The replication is performed by the DVSharedState.  However, in order for the replica to be used in the context of the process, it should be integrated with the other objects in the process.  The integration is application-specific.  For example, in the DVChatTest application, the DVChatTest object is made a property change listener of the replica of a shared DVStringBuffer, so that when the string value of the DVStringBuffer changes, the DVChatTest would be automatically notified.

In order to allow an application to access specific shared objects after joining a group, DistView allows the application to name shared objects, as in:

    ...
    aSharedObj.setDescription(objName);,
    ...

where aSharedObj is a shared DVObject, and objName is a String that represents the application-specific name of aSharedObj.  The setDescription() method is defined in the DVObject class.  In order to obtain a reference to a shared object after joining a group, the application should a complementary method defined in DVSharedState, called getDescription(), as in:

    ...
    int  ret = myGroup.join();
    if (ret == 1) { // the join() is successful
       DVObject aSharedObj = myGroup.getDescription(objName);
    }
    ...

The getDescription() call returns a DVObject whose name matches to the specified String value.

The following figure shows the architectural overview of the DVChatTest application that shares a DVStringBuffer, and its source code is found in this version of  DVChatTest.java:

Note that this version of DVChatTest first adds an instance of DVStringBuffer to a DVSharedState, regardless of whether the application is creating a new group, or it is joining an existing group.  In the former, the added DVStringBuffer becomes shared among the DVChatTest processes that join the created group.  In the latter, the added DVStringBuffer is disregarded by the DVSharedState upon joining the existing group.  Also note that the DVChatTest object becomes a property change listener of the shared DVStringBuffer.  However, other approaches are possible.  For example, the shared DVStringBuffer can be an action listener to the "Send" button in the DVChatTestFrame, and the display TextField in the DVChatTestFrame can be a property change listener.
 
 

Example 2:  TestClient

A TestClient is a text-based (without GUI) application that shows the implementation and usage of a simple
client of the DistView toolkit. A TestClient connects to the server, joins a communication group, sends/receives broadcast messages and measures roundtrip delays for these messages. The communication between a TestClient and the Corona server is done through a DVSharedState object. Although it is not an applet, but an application, TestClient extends the DVApplet class, which is the base class used for the implementation of the DistView client applets (e.g., ChatBox, Whiteboard, etc).
The file TestClient.java contains the code for this application. For the purpose of colecting performance data, the TestClient is used in connection with the ReceiverClient (ReceiverClient.java), a simple client which connects to the server, joins a group and can only receive broadcast messages. A communication group contains multiple ReceiverClients and only one TestClient, which broadcast messages and measures the delays.

In order to run these applications, do the following:

A TestClient can also be used to cause the server print status information, a useful feature for debuggging and monitoring server activity.