| < Day Day Up > |
14.3. Leasing and Sponsorship
One of the signature features of .NET is its use of Garbage Collection to remove unused objects. As was discussed in Chapter 4, .NET maintains a graph to keep track of all references to objects in the managed heap. When Garbage Collection occurs, those objects for which references cannot be found are
The rather clever .NET solution is to assign a
lease
object to each client-activated object or server-activated singleton when they are created. (
As we see
Leasing
A lease is an object created internally by .NET that implements the
ILease
interface. This interface, located in the
System.Runtime.Remoting.Lifetime
namespace, defines the
Table 14-1. ILease Interface Members
Setting Initial Lease Values for Objects in an ApplicationYou can override the default values assigned to lease properties in an application's configuration file. For example, to set the lease values for all objects in our image server example, insert the following into the caoimagehost.exe.config file:
<application >
<lifetime
leaseTime = "8M"
renewOnCallTime = "6M"
/>
...
</application>
In this example, the time is specified in minutes (
M
), but it may also be specified as days (
D
), hours (
H
), seconds (
S
), or
The same effect can be achieved inside a program by setting static properties on the LifetimeServices class:
LifetimeServices.LeaseTime = System.TimeSpan.FromMinutes(8);
LifetimeServices.RenewOnCallTime =
System.TimeSpan.FromMinutes(6);
Setting the Lease Values for an Individual ObjectBoth of the aforementioned techniques for setting initial lease values apply to all objects hosted by the server. To set lease values on an object-by-object basis, a different approach is required. Recall that for a class to implement remoting it must inherit the MarshalByRefObject class. This class includes an InitializeLifeTimeService method that is responsible for returning lease objects. It is a simple matter to override this method in a program to assign your own initial values to the lease object.
using System.Runtime.Remoting.Lifetime; // Contains ILease
public class MessageManager: MarshalByRefObject, IMessageManager
{
// Override this method to set lease initialization values
public override object InitializeLifetimeService()
{
ILease msgLease = (ILease)base.InitializeLifetimeService();
msgLease.InitialLeaseTime = TimeSpan.FromMinutes(8);
msgLease.RenewOnCallTime = TimeSpan.FromMinutes(6);
return msgLease;
}
Note that implementation of this method
After a lease is in an active state, the only property on the lease that can be changed is its CurrentLeaseTime . This value can be renewed by a sponsor (described later) or by having the client or object explicitly invoke the lease's Renew method.
// Client
(ILease) lease=(ILease)RemotingServices.GetLifetimeServices(ob)
// Object on server
(ILease) lease=(ILease)RemotingServices.GetLifetimeSer-
vices(this)
if(lease.CurrentLeaseTime.TotalMinutes < 1.0)
lease.
Renew
(TimeSpan.FromMinutes(5));
If the current lease time is greater than this renewal time, the lease is not reset. The Lease ManagerRunning in the background of each AppDomain is a lease manager that keeps track of each server object and its associated lease. The primary function of the manager is to periodically examine the leases for time expiration and invoke a sponsor if the lease has expired. The lease manager uses a timer to control how frequently it checks for lease expirations. By default, this is set to 10 seconds. To override the default, add this setting in the configuration file:
<application >
<lifetime
LeaseManagerPollTime"5S"
/>
The value can also be set programmatically using the LifetimeServices class:
LifetimeServices.
LeaseManagerPollTime
=
System.TimeSpan.FromSeconds(5);
The Lifetime of a LeaseIt should be clear from the discussion thus far that a lease has a nondeterministic lifetime whose actual length is determined by calls on the associated object, direct invocation of the lease's Renew method, and any renewal coming from a lease's sponsor(s). The state diagram in Figure 14-12 illustrates the relationship between these actions and the current state of a lease. Note that a lease may be in one of four states—Initial, Active, Renewing, or Expired. Figure 14-12. Different states in which a lease may exist
When a remote object is created, .NET creates a corresponding lease and sets its
InitialLeaseTime
—in descending order of priority—to either a value set programmatically, a value in the configuration file, or a default value of 5 minutes. The lease moves into an active state, and its time begins to tick away. When a call is made on the object, the remaining lease time is compared with the
renewOnCallTime
value. The lease time is set to the greater of the two values. For example, if 4 minutes remain, and the renew time is 6 minutes, the value is set 6 minutes; if 7 minutes
SponsorshipA program's final opportunity to renew a lease is when the lease's CurrentLeaseTime value winds down to 0. At this point, the lease enters a LeaseState.Renewing state (see Figure 14-12), and the lease manager checks to see if any sponsor has been registered with the object (a lease may have sponsors created by multiple clients). If a sponsor is found, it is called and given the opportunity to renew the lease by returning a TimeSpan value that becomes the new TTL for the object.
This sponsorship model, based on registration and callbacks, closely resembles the .NET event handling model. In fact, a sponsor can be
Table 14-2. Similarities Between an Event Handler and a Sponsor
Although an event handler is a method, a sponsor is a class that meets two requirements: It inherits from MarshalByRefObject , and it implements the ISponsor interface: public class ImageSponsor: MarshalByRefObject, ISponsor The ISponsor interface defines only one member—a method, Renewal —that returns the new TTL value for the object as a TimeSpan type: public TimeSpan Renewal(ILease lease)
A sponsor can be implemented on the server, client, or in a third-party assembly. The only requirement is that the lease manager can locate it. In reality, a sponsor should be defined where the application can best assess the factors that determine how or if an object's lease is extended. For an SAO singleton, this is on the server/host; for a CAO, the code should be on the client, because only the client
To
In this example, the sponsor renews the lease for 10 more minutes. Because this sponsor is called each time the TTL approaches 0, the object associated with the lease exists as long as the client is running. A more sophisticated implementation would include logic that decides whether to renew the lease. To
|
| < Day Day Up > |