Sensei


Overview

Design

Sensei GMS

Sensei Domains

Sensei GMNS

Sensei UMA

Code

IDL specification

Download & Build

Configuration

Examples

Documentation

Links


Last Updated:
30th May 2004



My personal homepage java_lmp@yahoo.co.uk
Sensei GMNS


Overview

As explained in the SenseiGMS section, the basic subsystem does not define public operations to create or extend groups. This functionality is shifted to this subsystem, being implemented in two different ways:

  • Basic service: defines two operations, create and join.
    In case of using join, the client must supply a reference to a member in the group to join.
  • Naming service: the GMNS associates names to groups, and the client must only specify the name of the group to use: the GMNS server creates a group or extends it if already present.

Although the naming service is more appealing, it involves much more effort. A specific application, the GMNS server, must be running; and, to achieve fault tolerance, this server must be itself replicated; the user should specify the right configuration values in order to use it properly.

The IDL specification of this service is given in the file GroupMembershipNamingService.idl.

The RMI definition is given in the package sensei.middleware.gmns under the rmi structure. Note that this directory includes not only the RMI definition for the service, but also the RMI definitions for the internal implementation.


Basic service

The basic service is implemented through the interface GroupMembershipBasicService, defined as:

interface GroupMembershipBasicService
{
	GroupHandlerFactoryCreator getFactoryCreator();
	GroupHandler createGroup(in GroupHandlerFactory theFactory)
		raises (InvalidGroupHandlerFactoryException, 
		        GroupHandlerFactoryException);
	GroupHandler joinGroup(in GroupHandler group, 
	                       in GroupHandlerFactory theFactory)
		raises ( InvalidGroupHandlerException,
		         InvalidGroupHandlerFactoryException,
		         GroupHandlerFactoryException);
};

When a group is joined or created, a GroupHandler is returned to the client. This interface includes two new types: GroupHandlerFactory and GroupHandlerFactoryCreator.

The GroupHandlerFactory follows the factory pattern, being responsible to create new GroupHandler objects:

interface GroupHandlerFactory
{
	GroupHandler create() raises (GroupHandlerFactoryException);
};

The objective of this type is to be able to create the GroupHandler object in the client's machine. Why is this needed? An application's instance, implementing the GroupMember interface, communicates with its group through a GroupHandler object. As the goal is to have fault tolerance, this GroupHandler object should reside on the same machine (and process) as the associated GroupMember. For this reason, the GMNS, that can be hosted on a different machine, is not responsible to create itself the GroupHandler, it delegates this functionality to a GroupHandlerFactory, which must be supplied by the client.

To facilitate this scenario, there is as well a factory for the factory itself:

valuetype GroupHandlerFactoryCreator
{
	GroupHandlerFactory create(in GroupMember member) 
		raises (GroupHandlerFactoryException);
};

Note that this type is defined as valuetype: it can be created on the GMNS server, then used in the client's host to create the factory itself (which is therefore created in the client's, not in the GMNS).

A normal scenario is therefore:

  1. Get reference to the GroupMembershipBasicService
  2. Request a GroupHandlerFactoryCreator to this service
  3. Use this GroupHandlerFactoryCreator to create, on the client, a GroupHandlerFactory associated to the application's GroupMember
  4. Use this GroupHandlerFactory to create or join a group, passed as parameter to the GroupMembershipBasicService

An example using this service is the TestMonitor class in the Concurrency example. (it uses optionally the more advanced Naming Service).


Naming service

The naming service uses the concepts of GroupHandlerFactory and GroupHandlerFactoryCreator explained for the basic service.

The interface GroupMembershipNamingService is defined as:

interface GroupMembershipNamingService
{
	GroupHandlerFactoryCreator getFactoryCreator();

	GroupHandler findAndJoinGroup(in string groupName, 
	                              in GroupHandlerFactory theFactory,
        	                      in string memberName, 
	                              in ReplicatedServer clientsReference)
		raises (MemberStateException,
		        InvalidGroupHandlerFactoryException,
		        GroupHandlerFactoryException);

	void leaveGroup(in string groupName, in GroupHandler member);

	ReplicatedServersList getGroup(in string groupName) 
		raises (MemberStateException);
	
	ReplicatedServer getGroupServer(in string groupName, 
	                                in string memberName)
		raises(MemberStateException);
	
	ReplicatedServer getValidGroupServer(in string groupName)
		raises(MemberStateException);
};

There is just one operation to create or extend a group: findAndJoinGroup, where the group's name must be supplied.

As difference with the basic service, now the members that use the naming service can give notice of their exclusion from their groups. This notification speeds up the process, although is not strictly required: the GMNS server checks periodically the groups to verify excluded members.

This interface is also useful for clients of the group. The server can register here a interface to be used by clients, which must inherit from ReplicatedServer, an empty definition:

interface ReplicatedServer
{
};

It must be noted that every group member must implement the GroupMember interface, to receive events from the group. But these group members have usually a server role, represented by a specific interface to be used by the clients. The GMNS server registers this interface, to be returned to any client.

The GUI of the SenseiGMNS server has the following appearance:

For each group, the GMNS lists the members that have been registered through the GMNS server. For these members, it shows the name used at registration time, or 'unknown' if none is given. If the member has not specified a ReplicatedServer interface (is null), the name is shown in italic, like it happens in the previous figure.


The SenseiGMNS server: execution and access

The server is executed with the script gmns.sh or gmns.bat. More information on how to execute it is found in the Example section (section scripts).

The server is usually executed as a replicated instance, that is, several instances working in a group as a single server. To do it properly, the configuration file must be carefully specified. Please refer to the Configuration section.

The client must specify the same GMNS configuration data in order to access the GMNS. On a normal scenario, there is one GMNS server on each host, and therefore it is enough that the client specifies this GMNS on the configuration file. Nevertheless, to specify the whole list of possible GMNS servers can avoid problems in case that the host's server is not available.

Currently, the GMNS server does not register itself in the RMI registry or in the CORBA naming service: the reason is its replicated nature. Should it register on every possible host? Is the user going to use just one naming service in a specific host, or perhaps two for fault tolerance? What the server does is to publish its reference into a specific file or TCP/IP port, depending on the configuration values.

A Java client can use the class sensei.gmns.GroupMembershipNamingServiceFactory to locate the service (using the same configuration values). For example, in the Random Counter example, it does:

import sensei.gmns.GroupMembershipNamingServiceFactory;
import sensei.middleware.gmns.GroupMembershipNamingService;

   GroupMembershipNamingService service = GroupMembershipNamingServiceFactory.load();
   if (service==null)
   {
     System.err.println("GroupMembershipNamingService is not available");
   }

Implementation

The directory containing the IDL specification for the GMNS service includes some IDL files in addition to the GroupMembershipNamingService specification. These files are used on the implementation of the GMNS server.

This server is implemented on top of SenseiDomains using replicated components. The data structures must deal with:

  • The server needs to keep a list of the existing groups.
  • Each group must contain the list of existing members.
    For each member, it is needed to store its name, reference, and client's reference (ReplicatedServer instance).
  • A group is therefore identified by a name, and the list containing the existing members.

Following components are therefore required:

  • MemberInfo, defined in MemberInfo.idl: contains the information related to a specific member (name and references).
    This component is not replicated itself (just an struct).
  • SetMemberInfo, defined in SetMemberInfo.idl: this is a replicated component, containing the list of objects MemberInfo. It is a set because the same member cannot be contained twice.
  • MapStringSet, defined in MapStringSet.idl: this is as well a replicated component, a map associating strings (the group name) to SetMemberInfo components.

When a GMNS server requires to add a new group, it creates a new SetMemberInfo component, which is automatically replicated over all the instances. It must then include the member in its SetMemberInfo, but the MemberInfo object that is included is automatically sent to the other replicas, that perform the same inclusion. And finally, it associates the SetMemberInfo object with the group's name in the MapStringSet. Again, this operation is performed on every replica.

This logic must be executed with replicated monitors, to avoid concurrency problems if other replica tries to do some incompatible operation.

The main advantage on using the component's philosophy embedded in SenseiDomains is that the main logic is exactly like in a multithread application: the code is the same, including the use of monitors. The complexity comes out from the need to write the individual components. But this is a goal of SenseiUMA: to provide the more usual containers as replicated components. And a Map or a Set are of course the kind of containers to be implemented in SenseiUMA.

The IDL specification for SenseiGMNS includes still other file, GroupsCheckerState.idl: this file defines the checking state for every GMNS instance. The GMNS server must check periodically whether the registered instances are alive or have felt down or just excluded from their groups. But it is not needed that every replicated GMNS server performs this checking, just one. The GroupsCheckerState defines the identity of the GMNS server that is responsible for this task.

A complete description of this implementation is given in the chapter 11 of my thesis (only in Spanish).