The leasing concept enjoys increasing popularity in the context of distributed systems â a prime exam- ple for this is Jini. In this paper, we present a service.
Design and Implementation of a Leasing Service for CORBA-based Applications – Extended Web Version Markus Aleksy, Ralf Gitzel University of Mannheim, Germany {aleksy|gitzel}@wifo3.uni-mannheim.de Abstract The leasing concept enjoys increasing popularity in the context of distributed systems – a prime example for this is Jini. In this paper, we present a service that realises the leasing concept for the CORBA environment. We discuss various resource management techniques with regard to CORBA and detail their advantages and disadvantages. The focus of this work, however, is the description of the design and implementation of our CORBA leasing service. Special care was taken to incorporate existing types defined in the CORBAservices specification to allow users familiar with other CORBA services to quickly grasp the newly-introduced leasing service.
1.
•
Introduction
Currently, many technologies exist for the development of distributed and/or parallel applications. In the field of object oriented distributed systems the Common Object Request Broker (CORBA) standard [4] is in wide-spread use. Not only does it offer independence with regard to computer architectures, operating system, and programming language, it is also offers interoperability between the ORBs produced by different vendors, thanks to the introduction of the Interoperable Object Reference (IOR) and the interinter-ORB protocol (IIOP) in CORBA 2.0.
2.
One disadvantage of the current specification, however, is the fact that sensible resource management is insufficiently addressed. If a CORBA client were to request the services of a CORBA object for some time, one of the following scenarios would take place:
Motivation
CORBA’s communication model allows the development of applications that go beyond the basic client-server architecture. Concepts like multi-tier architectures or peer-to-peer systems are naturally realised with CORBA. A multi-tier architecture uses several servers with different responsibilities that are used by servers that directly cater to the client. Peerto-peer systems completely abandon the concept of client and server with each participating node taking aspects of both.
• •
•
In the case of unshared CORBA objects each object can only be used by a single client at any given time, even tough these objects may be reused by other clients after the original client has given up control. Unshared objects are usually obtained via a factory method since the platform independent nature of CORBA makes it impossible to directly instantiate remote objects. Another method is offered by the Life Cycle Service [6], which has the drawback of being implemented by nearly no ORB vendor. Pools of unshared objects lessens the problems associated with the object creation and destruction overhead. In the case of a shared CORBA object, i.e. an object that is a singleton, it is necessary to claim the object only as long as required to increase availability to other clients Pools of shared objects are less stringent with regard to minimising usage time but unnecessary blocking of objects is still detrimental to performance.
In all of the above cases, objects can be out of use yet still be claimed by clients that did not release them. Reasons for this might be technical, such as poorly implemented client applications, the actual breakdown of a client, user errors, or disrupted network connections. Even with object pools there is still the danger of not being able to service a client request which makes it desirable to invent a service for resource management, especially since there is currently no distributed garbage collection mechanism for CORBA. One technique of resource management is the Evictor pattern ([1], [2]). This approach uses monitor-
ing to ensure efficient use of resources. It is based on the assumption that resources least recently used (LRU) or least frequently used (LFU) are candidates for automatic release. The exact algorithm varies, either one or both values can be used by it. This technique would best be implemented using the special functionality of the Portable Object Adaptor (POA) – a service based implementation would be burdened by communication overhead. The solution presented in this paper is called Leasing. The Leasing concept is already employed by technologies such as Jini [9]. Jain and Kircher [3] have introduced the concept of a Leasing pattern and unveil the details, structure and variants possible for Leasing. The core concept of Leasing is the temporal restriction of resources, i.e. when these are assigned to clients a time limit is set, after which the client is no longer allowed to use the resource.
3.
The CORBA Leasing Service
In order to allow CORBA-based applications to use their resources efficiently, we have implemented a Leasing Service. The following sections highlight the interfaces comprising the service, as well as their interactions.
3.1. •
•
•
Design Considerations Service Approach: CORBA services are conceptually extensions of the ORB functionality, providing frequently required services. A CORBA service can be used by any program, regardless of the language it was written in, as long as said language has an Interface Definition Language (IDL) binding. The Leasing functionality fits this description and is therefore best implemented as a service. Flexibility: By using a broad definition of the term ‘resource’ (in fact practically any CORBA object) the Leasing service can be used for a myriad of applications. Also, different types of resource claiming techniques are supported. Use of Existing Data Types: In order to minimise the initial learning period for users of the Leasing Service, existing data types have been used. These are TimeBase::TimeT from the Time Service Specification [8] and CosEventComm::PushConsumer from the Event Service Specification [5]. Furthermore method names are based on the conventions found in both the Event Service Specification and the Li-
censing Service Specification tain...).
3.2.
[7] (e.g. ob-
Leasing Considerations
There are several approaches to leasing with decreasing strictness. Strict Leasing immediately revokes a client’s right to use a resource as soon as its time slot is used up and assigns it to the next requestor. The problem here is that this requires the resource user to partition its task, if the total computational time required for it exceeds the time slot. Depending on the algorithm this can be quite complex thus increasing the difficulty of implementation, comprehension, and maintenance. Therefore, this approach is only recommended for mission-critical resources. A weakened variant of the Leasing concept allows clients to extend their allocated time slot, but not arbitrarily. One has to be careful, however, because the more extensions the service allows, the less effective the resource management becomes. If used sensibly (i.e. with a reasonable extension time) the second option is preferable in most cases.
4.
The Components of Our Solution
The CORBA Leasing Service consists primarily of the following interfaces: • • • •
Resource ResourceClaimant Lease Lessor
These interfaces are detailed in the following sections.
4.1.
Resource
In our implementation, a Resource is opaque, i.e. the Leasing Service itself does not interpret the functionality offered by the Resource. It only expects to be informed about the type of the Resource, as well as two methods to inform the Resource which client is going to use it and when this usage ends. The method start_use informs the Resource that it is in use again so it can reset to an initial state. When a time slot ends stop_use is called which can be used to free system resources allocated before.
abstract interface Resource { void start_use( in Lease l, in ID rid); void stop_use(in ID rid); }; The argument rid is assigned by the LessorComponent of the Ressource to allow authentication of the caller.
4.2.
anonymous claimants observed claimants notified claimant
Anonymous claimants are clients that do not contain CORBA objects, since this denies the Lessor the possibility to hold a remote reference on the client. Observed claimants implement the remote interface ObservedResourceClaimant. While the client obtains a normal lease, the Lessor is able to observe the client and make the resource available again should the client terminate prematurely. The NotfiedResourceClaimant is informed by the Lessor as soon its lease terminates. However, the time slot is prolonged once to ensure that the client has ample reaction time.
4.3.
interface Lease { typedef any Key; Key get_key(); void renew(); void renew_with_modified_time( in TimeBase::TimeT time) raises(TimePeriodOutOfBound); void cancel();
Resource Claimant
A resource claimant is a user of Resources. Direct access to resources is not allowed though. Instead the claimant has to obtain a Lease (see 4.3) from a Lessor-Component. There are three different types of ResouceClaimants: • • •
claimants by calling get_key(). This key allows a resource to authenticate the client attempting to use it. The following code fragment taken from the IDL definition shows the Lease interface:
Lease
The Lease is the link between the claimant and the resource, which can be revoked as soon as the assigned time slot expires. In order to achieve this, several administrative methods are provided by the Lease interface. renew reThe methods and new_with_modified_time allow a resource claimant to prolong the lease time slot. cancel allows the claimant to prematurely release a resource it no longer needs. When it is created, the Lease generates a key, which can be checked by both the resource and its
};
4.4.
Lessor
The Lessor interface provides methods for both the resources and claimants. Resources can register Lessor regiswith the by calling ter_resource and unregister with unregister_resource. Claimants are offered methods for browsing and leasing resources. Browsing functionality is provided by the listmethods. It is possible to get a list of all available resource types, all available instances of one type, or all unclaimed instances of a resource. The use of the latter method is not recommended since a resource instance may be claimed by another client in the time between receiving the list and sending the request. A more sensible way to obtain a resource is described below. The remaining methods allow clients to obtain a lease on a resource. An anonymous resource claimant can obtain a lease by calling either obtain_ lease_by_resource or obtain_lease_by_ type. ObservedResourceClaimants use the methods obtain_lease_by_resource_ with_client_observation or obtain_ lease_by_type_with_client_observation. Finally, obtain_lease_by_resource _with_expiration_notification and, obtain_lease_by_type_with_expiration _notification are responsible for supplying NotifiedResourceClaimants with leases. As the method names suggest, there are two different types of obtain when one ignored the claimant type for the moment. The first type requests a lease on a specific instance of a resource. This might be a suitable course of action, when the client has a preference for a certain instance, e.g. one that has met its requirements in the past or is known to be the most
efficient due to meta-knowledge on behalf of the designer. The second type, on the other hand, requests a resource specified by type. The Lessor can satisfy this request with any instance of this type, depending on availability. Therefore, multiple calls of this method will very likely result in the assignment of different instances of the resource – a fact which can be important for certain implementations. The following code fragment is taken from the IDL-Definition shows the interface Lessor:
TimePeriodOutOfBound, AlreadyInUse, NotFound); Lease obtain_lease_by_resource_with_ expiration_notification( in Resource res, in TimeBase::TimeT time, in NotifiedResourceClaimant nrc) raises( TimePeriodOutOfBound, AlreadyInUse, NotFound);
interface Lessor { exception AlreadyInUse { }; exception NotFound { }; exception IllegalType { };
Lease obtain_lease_by_type( out Resource res, in Type t, in TimeBase::TimeT time) raises( TimePeriodOutOfBound, IllegalType, AlreadyInUse, NotFound); Lease obtain_lease_by_type_with_ client_observation( out Resource res, in Type t, in TimeBase::TimeT time, in ObservedResourceClaimant orc) raises( TimePeriodOutOfBound, IllegalType, AlreadyInUse, NotFound); Lease obtain_lease_by_type_with_ expiration_notification( out Resource res, in Type t, in TimeBase::TimeT time, in NotifiedResourceClaimant nrc) raises( TimePeriodOutOfBound, IllegalType, AlreadyInUse, NotFound); };
typedef string Type; typedef sequence TypeSeq; typedef sequence ResourceSeq; ID register_resource( in Resource res, in Type t); void unregister_resource( in ID rid); TypeSeq list_available_types(); ResourceSeq list_resources_by_type( in Type t) raises(NotFound, IllegalType); ResourceSeq list_unused_resources_by_type( in Type t) raises(NotFound, IllegalType); typedef Object ObservedResourceClaimant; typedef CosEventComm::PushConsumer NotifiedResourceClaimant; Lease obtain_lease_by_resource( in Resource res, in TimeBase::TimeT time) raises( TimePeriodOutOfBound, AlreadyInUse, NotFound); Lease obtain_lease_by_resource_with_ client_observation( in Resource res, in TimeBase::TimeT time, in ObservedResourceClaimant orc) raises(
5.
UML Component Diagram
Figure 1 shows a UML Deployment Diagram corresponding to our implementation. It is an instance level diagram depicting a snapshot of a system implementing the Leasing Service approach at runtime. The different computational nodes, e.g., the computer on which the master is running, the network etc., are symbolized by 3D boxes. The CORBA objects implementing resources, resource claimants, leases and the Leasing Service are modeled as UML components with explicit interfaces (shown in “lollipop” notation) which represent their IDL interfaces.
:ResourceClaimantMachine
rc:ResourceClaimant
:LeasingServiceMachine
lessor:Lessor
ResourceClaimant
Lessor
:ObservedResourceClaimantMachine
:ResourceMachine
r1:Resource Resource
l1:Lease
:ResourceMachine
Lease orc:ObservedResourceClaimant ObservedResourceClaimant
r2:Resource l2:Lease
Resource
Lease :NotifiedResourceClaimantMachine
:ResourceMachine
l3:Lease nrc: NotifiedResourceClaimant
Lease
NotifiedResourceClaimant
r2:Resource Resource
:Network
Figure 1: Deployment diagram of the Leasing Service scenario The solid lines between the nodes show hardware connections used for the actual flow of information. Dependencies between the components are expressed by dashed lines, e.g., a component uses an interface of another component. For example, the ResourceClaimant component depends on the Lessor interface of the :Lessor component in order to be able to receive a list of available resources by calling operation list_resources_by_type. Let us have a look at an example scenario of the use of the Leasing Service, where the claimant has a preference for a specific instance of a resource type. The UML sequence diagram in Fig. 2 shows the dynamic flow of messages in the scenario described below. The example begins with the registration of a resource with the leasing service. In the next step (which does not necessarily occur right after the registration process) a resource claimant desires the
services of the resource. In order to find out what resource types are available, the claimant calls list_available_types. If the type required is available from this specific leasing service, all available instances can be obtained by calling list_resources_by_type. According to its preferences, the claimant can now try to obtain a lease on its chosen instance by calling obtain_lease_by_resource. Unless the resource has been claimed in the meantime, the Lessor creates a new instance of Lease (or takes one from an object pool) and starts usage of the resource by calling start_use. A pool of Lease objects has the advantage of avoiding creation overhead. After obtaining the lease, the resource is used and – in the example at hand – its time slot is extended by calling renew after its expiration.
client:ResourceClaimant
lessor:Lessor
resource:Resource ID = register_resource(this,type)
types = list_available_types() resources = list_resources_by_type(type) lease = obtain_lease_by_ resource(resource) lease:Lease start_use(this,ID)
use(...) leasing time
use(...) renew() use(...)
leasing time
use(...) stop_use(ID)
Figure 2: An example scenario of the Leasing Service at work After the end of the second time slot, the claimant does not renew the lease again and therefore the resource is set free by the Lease.
6.
Programming Examples
After explaining the underlying concept with the help of Fig. 2, we now present examples for typical implementations of the resource and the resource claimant.
6.1.
Implementation of a Resource
As the interface Resource is abstract, it is necessary to provide another interface that describes the actual resource and inherits from Resource. This interface provides all the additional attributes and operations for the actual resource functionality. The following IDL-interface provides an example:
#include "LeasingService.idl" module Example { interface MyResource : LeasingService::Resource { void print( in any key, in string text); }; }; The print operation represents the business logic of the resource. The argument key, which has the type any, serves authentication purposes. The IDL-interface has to be implemented in a programming language such as Java. The following class is an example with minimal business logic:
import org.omg.CORBA.*; import LeasingService.*; import Example.*; class MyResourceImpl extends MyResourcePOA { private boolean inuse = false; private int id; private Any key; public void start_use( Lease lease, int id) { if(this.id == id) { key = lease.get_key(); inuse = true; } } public void continue_use(int id) { if(this.id == id) inuse = true; } public void stop_use(int id) { if(this.id == id) inuse = false; } public void print(Any key, String message) { int key1 = this.key.extract_long(); int key2 = key.extract_long(); if(key1 == key2) { if(inuse) System.out.println(message); else System.out.println( "Expired!"); } else System.out.println( "Invalid key");
step, the claimant requests a list of all resources of type "IDL:MyResource:1.0". Next, it requests a 10 second lease on the first instance of MyResource. Since this resource type authenticates users, the claimant has to obtain a key from the Lease object and passes it as a parameter for the call of print. The cancel operations ends the lease before the expiration of the allocated time. Please note that exception handling has been omitted for space reasons. Lessor lessor ; // get Lessor Resource[] res = lessor.list_resources_by_type( "IDL:MyResource:1.0"); Lease lease = lessor.obtain_lease_by_resource( res[0], 10); MyResource myres = MyResourceHelper.narrow(res[0]); Any key = lease.get_key(); myres.print(key, "Hello World !"); lease.cancel();
7.
Conclusion
The CORBA Leasing Service presented in this paper closes a gap in the current specification of CORBAservices, by implementing the lease concept in a CORBA environment. The implementation as a service allows all CORBA applications access to its functionality, regardless of the language they were implemented in. The Leasing Service is highly flexible, thanks to the high degree of abstraction in the definition of resource as well as the support of different types of resource claimants. Also, special care was taken to tightly integrate the service into the existing CORBA framework by making maximum use of existing elements. Not only does this ensure consistency, it also minimises the time needed to learn how to use this service.
}
References
void set_id(int id) { this.id = id; }
[1] Henning, M., Vinoski, S. (1999): “Advanced CORBA Programming with C++”; Addison-Wesley Longman
}
6.2.
Implementation of a Resource Claimant
The following code example shows how a resource claimant accesses the Leasing Service. In the first
[2] Jain, P. (2001): “Evictor”; Proceedings of 8th Patterns Languages of Programs Conference (PloP 2001), 11-15 September 2001, Allerton Park, Monticello, Illinois, USA
[3] Jain, P., Kircher, M. (2000): “Leasing”; Proceedings of 7th Patterns Languages of Programs Conference (PloP 2000), 13-16 August 2000, Allerton Park, Monticello, Illinois, USA [4] OMG, The Common Object Request Broker: Architecture and Specification Revision 2.6 (2001), OMG Technical Document Number 00-12-01, URL:
ftp://ftp.omg.org/ pub/docs/formal/00-12-01.pdf
[5] OMG (2001): “Event Service Specification Version 1.1”; OMG Technical Document Number 01-0301, http://www.omg.org/cgi-bin/doc?formal/2001-03-
01.pdf
[6] OMG (2000): “Life Cycle Service Specification Version 1.1”; OMG Technical Document Number 0006-18, http://www.omg.org/cgi-bin/doc?formal/2000-
06-18.pdf
[7] OMG (2000): “Licensing Service Specification”; OMG Technical Document Number 00-06-17,
http://www.omg.org/cgi-bin/doc?formal/2000-06-17.pdf
[8] OMG (2000): “Time Service Specification Version 1.0”; OMG Technical Document Number 00-0626, http://www.omg.org/cgi-bin/doc?formal/2000-06-
26.pdf
[9] Sun Microsystems Inc. (2001): “JiniTM Architecture Specification”; December 2001, http://www.sun.
com/jini/specs/jini1.2html/jini-title.html