Programming .NET Components : Remoting - Leasing and Sponsorship (part 1) - Lease Properties, Configuring a Lease, Renewing a Lease

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
12/2/2012 6:25:25 PM
.NET manages the lifecycle of objects using garbage collection. .NET keeps track of memory allocation and objects accessed by all the clients in the app domain. When an object becomes unreachable by its clients, the garbage collector eventually collects it. If the objects are in the same app domain as the clients, garbage collection functions fine. In fact, even in the case of a client in one app domain accessing an object in a different app domain in the same process, garbage collection still works, because all app domains in the same process share the same managed heap. In the case of remote objects accessed across processes and machines, however, the strategy breaks down because the object may not have any local clients. In this case, if garbage collection were to take place, the garbage collector would not find any references to the object and would deem it garbage, even though there are remote clients (on other machines, or even in separate processes on the same machine) who wish to use the object. The rest of this section addresses this challenge.

In the following discussion, a "remote object" is an object in a different process. The core piece of the .NET remoting architecture designed to address this problem is called leasing and sponsorship. The idea behind leasing is simple: each server object accessed by remote clients is associated with a lease object. The lease object literally gives the server object a lease on life. When a client creates a remote server object (that is, actually creates it, rather than connects to an existing instance), .NET creates a lease object and associates it with the server object. A special entity in .NET remoting called the lease manager keeps track of the server objects and their lease objects. Each lease object has an initial lease time. The clock starts ticking as soon as the first reference to the server object is marshaled across the app domain boundary, and the lease time is decremented as time goes by. As long as the lease time doesn't expire, .NET considers the server object as being used by its clients. The lease manager keeps a reference to the server object, which prevents the server object from being collected in case garbage collection is triggered. When the lease expires, .NET assumes that the server object has no remaining remote clients. .NET then disconnects the server object from the remoting infrastructure. The server object becomes a candidate for garbage collection and is eventually destroyed. After the object is disconnected, any client attempt to access it results in an exception of type RemotingException, letting the client know the object has been disconnected. This may appear strange at first, because the object may very well still be alive. .NET behaves this way because otherwise, the client's interaction with the remote object will be nondeterministic. If .NET allowed remote clients to access objects past their lease time, it would work some of the time but would fail in those cases in which garbage collection had already taken place.

If the remote object is disconnected because the lease has expired, the client can't call any method on it, including IDisposable.Dispose( ). This may have serious scalability consequences. When the object contains expensive resources, make sure to use single-call objects—these don't require leasing, and .NET calls IDisposable.Dispose( ) on them automatically.

But what about those cases where there are still some remote clients who would like to keep the server object alive after its lease expires? The smart thing to do is to contact such clients and ask them to extend the lease, or, in .NET terminology, to sponsor the lease. Clients that wish .NET to contact them when a server object's lease expires need to provide .NET with a special sponsor object. When the time comes, .NET will contact the sponsor object, giving it a chance to extend the lease. This interaction is illustrated in Figure 1.

Figure 1. Leasing and sponsorship

The sponsor can extend the lease or refuse to do so. A given server object can have multiple sponsors associated with its lease. The lease manager keeps a list of all the sponsors associated with each lease, and when the lease expires the lease manager starts traversing the sponsor list, looking for a sponsor willing to extend the lease. If such a sponsor is found, the lease manager extends the lease. Otherwise, the lease manager disconnects the server object.

1. Lease Properties

Every lease has a number of properties associated with it. These properties control the manner in which the lease manager interacts with the remote object's lease. .NET assigns some global default values to these properties, but you can instruct .NET to use other default values. You can even override the default lease properties for individual objects. The expired time is the time that has expired since the beginning of the lease. A lease has a lease time property. By default, if you don't configure it differently, each lease's lease time property is initially set to five minutes. .NET could simply disconnect the object when the expired time is equal to the lease time, but what should it do if clients continue to call the object? This clearly indicates that the object is still useful. Every lease has a renew on call time property; if the lease is about to expire, .NET automatically extends the lease on every call by the value set in the call time renewal property. The default call time renewal is two minutes. The current lease time value (the time the object has to live unless the lease is extended) is a product of the remaining lease time and the renew on call time, according to this formula:

    current lease time = MAX(lease time—expired time,renew on call time)

If the renew on call time value is less than the lease time minus the expired time, it will have no effect. The renew on call time has an effect only if it is greater than the lease time minus the expired time. In that case, the expired time property is reset, and the lease time is set to the renew on call time. The result is that even if an object is very busy, its lease time doesn't grow in proportion to the amount of traffic it has. Even if the object has a spike in load, after some quiet time, its lease will expire.

1.1. Lease manager properties

There are two properties pertaining to the lease manager itself. Obviously, the lease manager needs to monitor the leases of all remote server objects in its app domain. The question is, how often should the lease manager examine the leases? The lease manager's poll time property governs the frequency with which the lease manager polls the leases. The default poll time is set to 10 seconds. The other lease manager property has to do with sponsors. The lease sponsors can reside on remote machines, or it may take them a long time to reach a decision on the lease's fate. The lease manager's sponsorship timeout property controls how long the lease manager should wait for a reply from a sponsor. The sponsorship timeout is required to handle network failures, or even the case of a sponsor machine being down. If the lease manager tries to reach a sponsor and the sponsor doesn't reply within the sponsorship timeout period, the lease manager removes that sponsor from the sponsor list associated with the lease.

1.2. Configuring global default properties

If you don't like the default values of the various lease and lease manager properties, you can provide your own. You can do so both programmatically and administratively, using the application configuration file. To configure global defaults programmatically, use the static properties of the LifetimeServices class, defined in the System.Runtime.Remoting.Lifetime namespace:

    public sealed class LifetimeServices
       public static TimeSpan LeaseManagerPollTime { get; set; }
       public static TimeSpan LeaseTime            { get; set; }
       public static TimeSpan RenewOnCallTime      { get; set; }
       public static TimeSpan SponsorshipTimeout   { get; set; }

You typically use these properties in the Main( ) method of your host:

    static void Main( )
       LifetimeServices.LeaseTime       = TimeSpan.FromMinutes(10);
       LifetimeServices.RenewOnCallTime = TimeSpan.FromMinutes(15);
       /* Register types or load configuration file */

Note that you must set the global leasing defaults before you register types (programmatically or using the configuration file). The host can start servicing remote calls immediately after registration, and if you haven't already set the new defaults, these initial calls will not use them.

To provide the new global default values in the host configuration file, use the <lifetime> element:

              leaseTime = "10M"
              sponsorshipTimeOut = "1M"
              renewOnCallTime = "15M"
              LeaseManagePollTime = "8s"

2. Configuring a Lease

Every lease object implements the ILease interface, defined in the System.Runtime.Remoting.Lifetime namespace:

    public interface ILease
       TimeSpan CurrentLeaseTime   {get;}
       LeaseState CurrentState     {get;}
       TimeSpan InitialLeaseTime   {get;set;}
       TimeSpan RenewOnCallTime    {get;set;}
       TimeSpan SponsorshipTimeout {get;set;}

       void Register(ISponsor obj);
       void Register(ISponsor obj,TimeSpan renewalTime);
       TimeSpan Renew(TimeSpan renewalTime);
       void Unregister(ISponsor obj);

The ILease interface allows you to control and configure the lease properties for an individual object, as well as to manage sponsors for that lease. Both the object and its clients can obtain the ILease interface. An individual lease can be in one of a number of states; the most important are initial, active, and expired. You can obtain the state of the lease by accessing the CurrentState read-only property of the ILease interface. CurrentState is of the enum type LeaseState:

    public enum LeaseState

A remote class can provide its own values to the lease's properties, giving the object control over its lifetime. To do so, override the InitializeLifetimeService( ) method defined in MarshalByRefObject and return a lease object. .NET calls InitializeLifetimeService( ) immediately after the remote object's constructor, but before a reference to the object is marshaled back to the client. InitializeLifetimeService( ) is never called if a local client creates the object. Although you can return from InitializeLifetimeService( ) any object that implements the ILease interface, in practice you need to obtain the lease already associated with your object and modify its properties. You do that by calling your base class's InitializeLifetimeService( ) method and modifying the lease properties, as shown in Example 1. You can set the lease properties only if the lease is in the LeaseState.Initial state, and this is asserted in the example.

Example 1. Providing new lease properties for an object
public class MyServer : MarshalByRefObject
   public override object InitializeLifetimeService( )
      ILease lease = (ILease)base.InitializeLifetimeService( );
      Debug.Assert(lease.CurrentState == LeaseState.Initial);

      //Set lease properties
      lease.InitialLeaseTime    = TimeSpan.FromMinutes(30);
      lease.RenewOnCallTime     = TimeSpan.FromMinutes(10);
      lease.SponsorshipTimeout  = TimeSpan.FromMinutes(2);
      return lease;

3. Renewing a Lease

Both the object and its clients can extend the lease explicitly by obtaining the object's lease and calling the ILease.Renew( ) method, providing a new lease time. Renewing a lease explicitly affects the current lease time according to this formula:

    current lease time = MAX(lease time—expired time,renewal time)

This means that the renewal time will have an effect only if the renewal time is greater than the lease time minus the expired time. In that case, the expired time is reset, and the lease time becomes the renewal time. Consequently, if different clients all try to explicitly renew a lease, the lease will not grow to the value of their combined renewal sum; this ensures that the object remains connected only when clients require it. Both the client and the object obtain the lease associated with the object using the static method GetLifetimeService( ) of the RemotingServices class:

    public static object GetLifetimeService(MarshalByRefObject obj);

You can renew a lease only if it's in the LeaseState.Active state. For example, here is how a client renews a lease:

    MyClass obj;
    obj = new MyClass( );
    ILease lease = (ILease)RemotingServices.GetLifetimeService(obj);
    Debug.Assert(lease.CurrentState == LeaseState.Active);

If the object wants to renew its own lease, it simply calls GetLifetimeService( ), providing itself as the parameter:

    public class MyServer : MarshalByRefObject
       public void SomeMethod( )
          ILease lease = (ILease)RemotingServices.GetLifetimeService(this);
          Debug.Assert(lease.CurrentState == LeaseState.Active);
          //Do some work
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Video Sports
- The Banner Saga 2 [PS4/XOne/PC] PC Launch Trailer
- Welkin Road [PC] Early Access Trailer
- 7th Dragon III Code: VFD [3DS] Character Creation Trailer
- Human: Fall Flat [PS4/XOne/PC] Coming Soon Trailer
- Battlefleet Gothic: Armada [PC] Eldar Trailer
- Neon Chrome [PS4/XOne/PC] PC Release Date Trailer
- Rocketbirds 2: Evolution [Vita/PS4] Launch Trailer
- Battleborn [PS4/XOne/PC] 12 Min Gameplay Trailer
- 7 Days to Die [PS4/XOne/PC] Console Trailer
- Total War: Warhammer [PC] The Empire vs Chaos Warriors Gameplay Trailer
- Umbrella Corps [PS4/PC] Mercenary Customization Trailer
- Niten [PC] Debut Trailer
- Stellaris [PC] Aiming for the Stars - Dev. Diary Trailer #1
- LawBreakers [PC] Dev Diary #4: Concept Art Evolutions
programming4us programming4us