JIT Activation

In an enterprise system, a user-driven client application often creates an object, makes a method call, and holds on to the object to use it later. The time between calls can vary from seconds to minutes or even hours. Meanwhile, on the server side, the object continues to stay alive, potentially tying up expensive resources. Imagine the resource-sharing problem that would arise if 100 or more clients locked access to the resources that they weren't even using.

JIT activation is a mechanism provided by COM+ to manage the lifetime of an object more efficiently. The idea is very simple: The actual object is activated just prior to the first call made on it and is deactivated immediately after finishing its work.

For now, assume object activation is the same as object creation and object deactivation is the same as object destruction. The distinction will become clear in the next section when we discuss object pooling.

Configuration and Working

A serviced component is marked for JIT activation using the class JustInTimeActivationAttribute, as shown in the following code excerpt:

// Project JITActivation/Employee

[JustInTimeActivation]
public class Employee : ServicedComponent {
     ...
}

When a client instantiates a serviced component that is marked for JIT activation, COM+ activates the actual object and returns a proxy to the client. Subsequently, the client makes method calls on the proxy as usual. When the object has finished doing its work, COM+ deactivates the object. However, the client continues to hold the reference to the object via its proxy (unaware that the underlying object has been deactivated). Later, when the client makes a call on the proxy, COM+ activates a new instance of the object and associates it with the proxy that the client is holding.

Now comes the million-dollar question: How does COM+ know that it is safe to deactivate the object?

COM+ could perhaps wait for a predefined timeout period to check if the client makes any call. If no call comes in within this timeout period, then COM+ can deactivate the object. However, such a timeout-based deactivation mechanism may result in an unexpected behavior.

Consider, for example, our Employee serviced component:

public class Employee : ServicedComponent {
       private String m_employeeName;

       public String Name {
          get {return m_employeeName; }
          set {m_employeeName = value; }
       }

       public long GetSalary() {
          ...
       }
     }
}

The idea is that the client first sets the employee Name property, and then calls GetSalary to obtain the salary of the employee. Let's say the client doesn't call GetSalary within the timeout period. As a result, COM+ deactivates the object. Later, when a GetSalary call comes in, a new instance is activated. However, the new instance has no idea who the employee is on which GetSalary is being called. In the best case, the call returns a failure condition. In the worst case, it returns an invalid value.

The real problem is that when the original object was being deactivated, it was in a state that contained the name of the employee. When the object got deactivated, this state got lost.

For JIT to work, the object should be deactivated when it is "stateless," meaning it either contains no data, or contains data that is not important and may be discarded. But COM+ doesn't have the foggiest idea about the statelessness or the statefulness of an object. As far as it is concerned, the object is nothing but an implementation of a bunch of methods. Unlike COM+, however, the object does know what state it is in. If it can inform COM+ that it is done with the work it is supposed to do, COM+ can go ahead and deactivate the object.

In our example case, it is not okay to deactivate the object after setting the Name property but it is fine to deactivate the object after the client calls the GetSalary method.

An object that has JIT enabled internally contains a property called the "done" bit or, more precisely, the deactivate-on-return bit. COM+ checks this bit after returning from each method call. If the bit is turned on, COM+ deactivates the object.

To allow the serviced component to interact with COM+, System.EnterpriseServices provides a static class, ContextUtil. This class implements many properties that the serviced component can access or modify. The property that we are interested in currently is DeactivateOnReturn. Let's revise our GetSalary method to set this property to true. This is highlighted in the following code excerpt:

public long GetSalary() {
     if (null == m_employeeName) {
       throw new Exception("Set the employee name first");
     }

     ContextUtil.DeactivateOnReturn = true;

     // Return a hard-coded value for our demo
     return 100000;
}

Setting DeactivateOnReturn to true within GetSalary causes the Employee object to be deactivated after the method call completes. If you make a subsequent call to GetSalary, for example, a new instance of the ServicedObject is created automatically. However, as the employee name has not been set on the new instance, the implementation GetSalary simply throws an exception.

Although JIT activation results in reclaiming the resource taken up by the object, it is often less than what you think. Moreover, keep in mind that repeated activation and deactivation of the object results in some performance degradation. Before enabling JIT activation, you should consider if the benefit of saving resources outweighs the performance degradation. JIT activation has more of an advantage when deactivating an object recovers a scarce, expensive resource, such as a database connection.

The real benefit of JIT is that it enforces transactional correctness, as we will see later.

If JIT activation is enabled on a component, it implies that its objects are created and destroyed frequently. The primary intention of destroying an object is to force the object to release its resources. If somehow we can force the object to release its resources without actually destroying the object, we could reuse the object without having to create it, thus saving some CPU cycles. This is what object pooling, a COM+ provided mechanism and our next topic of discussion, tries to achieve. By pooling JIT-activated objects, you can greatly speed up object reactivation for the client.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.192.177