Archive for August, 2008

WS-Reliable Messaging

Posted: August 30, 2008 in Uncategorized, WCF
Tags:

In the next few posts I will be discussing about WCF Reliable Messaging.But prior to that, a discussion on the WS-Reliable Messaging(WS-RM) protocol is required to gain a better understanding.

Today’s Web Services are expected to work inspite of network failures and some sort of mechanism is required to ensure that messages are delivered properly inspite of such failures.Apart from that messages may be lost,duplicated or delivered in an incorrect order.WS-Reliable Messaging ensures guranteed message delivery between two endpoints.This is also referred to as the delivery assurance.There are four basic delivery assurances provided by the WS-RM

  • At Most Once – Message will be delivered at most once without duplication or error will be thrown in at least one endpoint.
  • At Least Once – Message will be delivered at least one point.
  • Exactly Once – Message will be delivered without duplication in at least one endpoint. 
  • Ordered – Messages will be delivered in the order in which they were sent.

The diagram below provides a simple view of the Reliable Messaging model.

 

  1. Application source is the endpoint that sends the message.
  2. The RM source transmits the message over the wire.
  3. The RM destination is the endpoint that receives the message and also sends an acknowledgement of the receipt.
  4. RM Destination also delivers the message to the Application destination or the end point that is supposed to receive the message.

WS-RM defines the spec to achieve this flow by introducing additional elements in the SOAP message header.The major elements are

  • Sequence – The sequence header block is key element used to track & assure message delivery.The main components of this are
    1. Identifier – This is an uniqueidentifier for the reliable session,which is used in all the subsequently exchanged messages.This is a must have element.
    2. MessageNumber – This is the ordinal position of the message within sequence.This is also a must have element.
    3. LastMessage – This indicates that a particular message is a last message in the sequence.

<wsrm:Sequence …>
<wsrm:Identifier …> xs:anyURI </wsrm:Identifier>
<wsrm:MessageNumber> xs:unsignedLong </wsrm:MessageNumber>
<wsrm:LastMessage/>
</wsrm:Sequence>

  • SequenceAcknowledgement – On sucessful receipt of a message RM Destination sends a SequenceAcknowledgement.This can passed as an indepdent message or can be piggybacked with a operation response.The key elements of this are
    • Identifier – This is the unique sequence identifier.This isa  must element.
    • AcknowledgementRange – Range of message numbers successfully received
    • Nack – Unreceived message in the sequence.

<wsrm:SequenceAcknowledgement …>
<wsrm:Identifier …> xs:anyURI </wsrm:Identifier>
[ <wsrm:AcknowledgementRange … Upper=”xs:unsignedLong” Lower=”xs:unsignedLong”/> + |
<wsrm:Nack> xs:unsignedLong </wsrm:Nack> + ] …
</wsrm:SequenceAcknowledgement>

  • CreateSequence – The RM Source creates the sequence by passing this message to the senders.
  • CreateSequenceResponse – The RM destination responds to a CreateSequence request using this header block.This includes the Identifier element.
  • SequenceTermination – After the RM Source receives acknowledgement of all the messages this message is sent out to inform the RM Destination that sequence will be terminated.based on this the RM Destination can release the resources.

The sequence of actions is somewhat like this:

The detailed specs can be found at:

specs.xmlsoap.org/ws/2005/02/rm/wsreliablemessaging.pdf

In the next post I will discuss about how WCF implements this Reliable Messaging….

Yesterday I have come across very interesting question:Should one use raw XML as string or Objects as parameters of methods for passing data between tiers.I mostly use objects for doing so.Initially I had a bias towards that approach.But after pondering over the subject I found that both the approaches has it’s own pros and cons and one should choose based mostly on the non functional requirements(performance/maintainability/developer expertise) for the system under discussion.

Object Approach

Pros

  1. All the advantages of object oriented programming and design can be very well used.Code will be simpler and very easy to understand.
  2. When used in WebMethods the schema will be extracted via wsdl as XSD and it will be easier for the client code to interpret the meaning and purpose of the object.

Cons

  1. When the object is to be passed beyond process/machine boundary it will be serialized.
    • For Web Services .NET Framework will be using the XML Serializer.
    • For Remoting it can be the Binary as well as the SOAP formatter
    • .NET XML Serialization internally generates an assembly at runtime for serialization.There will be one assembly per type passed to the constructor of the XMLSerializer constructor.Naturally there is a performance hit because of this.However this assemblies can be generated before hand using the tool SGen.exe.The detailed tips for improvement of XML Serialization can found in the patterns & practices guide.
  2. For any change in the object structure the proxies needs to updated.

 XML Approach

Pros

  1. No additional serialization overhead.
  2. For any change in the object structure the proxies needs not be updated.However this can sighted as a disadvantage as well as the client contract will hazy.Client has to know before the xml structure.There is should be some XSD validation in the service as well.

Cons

  1. Program will be complex as one has to use XMLDOM and Xpath to parse and read/write the values from/into the XML.

That’s all I can think of at this point.

But I would still prefer objects with XMLSerializer unless my performance requirements vs server infrastructure is not at all able to take the load.

WCF Transactions-Part I

Posted: August 20, 2008 in Transactions, WCF
Tags: ,

In this post I will discuss about the basics of implementing a transaction aware WCF Service.Like many other features of WCF a transaction aware service can be very easily implemented using the declarative programming model and configuration settings.
The important attributes related to transaction are:

TransactionFlow

This attribute determines how a transaction should flow from client to the service.The three options specified by the TransactionFlowOption enumeration are
1)Mandatory
This makes transaction flow from client mandatory.If there is no transaction flowing from the client then an exception will be thrown.Making TransactionFlow mandatory for a service operation makes the service too tightly coupled with the client as clients without a transaction will never be able to use this method.
2)Allowed
This indicates that a transaction may or not flow from the client and this is the most flexible of the three options.
3)Not Allowed
This indicates any client transaction flowing will not be allowed and an exception will be thrown.

To create a transaction aware service we have to make the TransactionFlow attribute of the service operation mandatory/allowed:

[TransactionFlow(TransactionFlowOption.Allowed)]  
[TransactionFlow(TransactionFlowOption.Mandatory)]

We also have set the transactionFlow attribute of the binding in the configuration to true

<wsHttpBinding>
 <binding name=”wsHttp” transactionFlow=”true” />
</wsHttpBinding>

These settings needs to be applied both at the client as well as server end.

TransactionScope parameter of OperationBehavior Attribute

This parameter of OperationBehavior attribute if set to true then the service will join the transaction flowing from the client else it will create a new transaction.If set to false then it will never participate in a transaction.The default value is false.

TransactionAutocomplete parameter of OperationBehavior Attribute


This parameter if set to true the transaction will complete if the operation executes without any exception.By default this is set to true.If  it is false then the transaction completion has to be done programmatically using the SetTransactionComplete method of the OperationContext class.

We need to perform the following steps to make a service transaction aware:
Server Side

  1. Set TransactionFlow attribute to Allowed/Mandatory.
  2. Set transactionFlow attribute of the binding in the configuration to true.
  3. Set the TransactionScope to true and TransactionAutocomplete to true.

Client side

  1. Set TransactionFlow attribute to Allowed/Mandatory in the generated proxy class.
  2. Set transactionFlow attribute of the binding in the configuration to true.
  3. Invoke the service operation within a TransactionScope

In the next post I will discuss about the TransactionIsolation/Timeout and Session.

Static Classes in C#

Posted: August 10, 2008 in .NET, CLR
Tags:

Normally in application development projects of any type we come across some sort of Utility classes, which has a bunch static methods for Date ,String .. etc manipulations.While reviewing code for the past few years I have seen two problems

  1. Some developers using object instances to access this methods without looking into the fact that they are static methods.
  2. During initial design & coding there are only static methods but down the line during support instance methods are getting added.

So we need to have a way where we can stop the instantiation of the class and addition of instance methods to it.

One option to do it in .NET 1.1 was making the class sealed with a private constructor.But that does not stop anyone from adding instance methods(of no use though) and private constructor takes up unnecessary metadata space.

In .NET 2.0 we have static classes for this purpose which can have only static members and can never be instantiated.

In my last post I had discussed about the Lightweight Transaction Manager(LTM) introduced with .NET 2.0.In this post we will take a look at MSDTC and how we can handle distributed transactions.
Microsoft Distributed Transaction Coordinator(MSDTC) can handle transactions with
1) Multiple Durable Resource Managers
2) Transaction Flow crossing process and machine boundaries.

As we have seen in the first post, in a transaction which is distributed across machines every box has a local transaction manager.The local transaction manager of the machine which initiates the transaction is called root transaction manager and it coordinates with local transaction managers in other machines.So all the transaction managers need to have a communication protocol for interacting messages over the network.For a distributed transaction across multiple windows machines each machine will have MSDTC as it’s local transaction manager and one of them will be the root.This is not a problem as MSDTC running on windows can communicate over network using RPC.

But what happens if one of the machines is running on Unix with a different transaction manager?

This is a question cross platform communication for distributed transaction related messages.Here also the Web Services standards come to our rescue.

There are two web Services standards for implementing this WS-coordination and WS-AtomicTransactions.
I will try to explain them briefly below:

WS-Coordination(WS-COOR)

This protocol defines an extensible coordination framework among different Web Services.It introduces a new SOAP Header block called Coordination Context.
The Web Service acting as a coordinator sends a Coordination context header to the target services.The target services upon receiving the coordination context analyses the information contained in the Coordination context header and decides to join the coordination or not.
The information contained in the coordination context depends upon the coordination type.The coordination types are open ended and new ones can be added.

WS-AtomicTransaction(WS-AT)

Atomic Transaction is one coodination type.This is built upon WS-Coordination framework and supports 2PC.But the messages are exchanged in SOAP format and thus achieving platform interoperability.

so to have distributed transactions with machines running on different platforms the local transaction manager supported by each platform should be able send and receive WS-COOR and WS-AT compliant XML messages over HTTP.

Weak References

Posted: August 9, 2008 in .NET, CLR
Tags: ,

Last sunday we had a session on .NET Internals as part of the monthly session of Kolkata .NET User group.The session went very well.But the discussion on what exactly happens for GC of a WeakReference class remained open ended.After going through Jeffrey Richters book “CLR via C#” I found lot of information on how the WeakReference class works.
For every app domain CLR maintains a table called GC Handle table.This table can be accessed via the System.Runtime.InteropServices.GCHandle class.Along with GCHandle there is an enumeration called GCHandleType which needs to be passed to the Alloc method of GCHandle class
The four values of this enumeration are:
1)Weak – This handle type is used to track an object, but allow it to be collected. When an object is collected, the contents of the GCHandle are zeroed. Weak references are zeroed before the finalizer runs.
 
2)WeakTrackResurrection-This handle type is similar to Weak, but the handle is not zeroed if the object is resurrected during finalization.

3)Normal-This handle type is used to track an object and prevent its collection by the garbage collector. This enumeration member is useful when an unmanaged client holds the only reference, which is undetectable from the garbage collector, to a managed object.

4)Pinned-This handle type is similar to Normal, but allows the address of the pinned object to be taken. This prevents the garbage collector from moving the object i.e. perform compaction.

WeakReference class is wrapper around GCHandle class with the GCHandleType –  Weak and WeakTrackResurrection.WeakReference constructor calls to GCHandle’s Alloc method and Target is same as the Target property of GCHandle class.

One of the overloaded constructor of this class is WeakReference(Object, Boolean).The boolean parameter if false then it is called a short weak reference otherwise a long weak reference.By default it is always short weak reference.

Short Weak Reference

The target of a short weak reference becomes null when the object is reclaimed by garbage collection.(Weak)

Long Weak Reference

A long weak reference is retained after the object’s Finalize method has been called. This allows the object to be recreated, but the state of the object remains unpredictable.(WeakTrackResurrection)

The GC in the marking phase also scans this GC Handle table to identify the object is reachable/unreachable.

As per MSDN Guidelines for Using Weak References are

 Use long weak references only when necessary as the state of the object is unpredictable after finalization.

 Avoid using weak references to small objects because the pointer itself may be as large or larger.

 Avoid using weak references as an automatic solution to memory management problems. Instead, develop an effective caching policy for handling your  application’s objects.
 

I found a very good suggesstion in Jeffrey Richters book in this regard.GC does not occur when the memory is full but occurs when the Generation 0  becomes full which is after 256 KB of memory allocation.So using WeakReference might lead to collection & re-creation of a memory intensive object  even when there is no memory crunch.This can result in significant performance hit.So while using WeakReference for caching scenario we have to  strike a balance between memory usage and appliaction performance.The caching algorithm needs to be designed with care and adhoc usage of  WeakReference will not solve the problem.

In my last post I had discussed about the basics of transactions,transaction manager & resource manager.In this post we will discuss about the Lightweight Transaction Manager(LTM) a transaction manager introduced with .NET 2.0.
Prior to LTM the only transaction manager available in the Microsoft world was the Micrsoft Distributed Transaction Coordinator(MSDTC).This transaction manager is able to handle transaction flowing across process/machine/network boundaries.But MSDTC has it’s own overheads and which is not required for simple transactional scenarios.That’s why the LTM was introduced.
LTM can manage transactions with
a) Any number of volatile resource managers
b) Single durable resource manager
c) No flows across process/machine
When anyone of the above mentioned conditions is violated the transaction gets promoted/escalated to the MSDTC or Kernel Transaction Manager(introduced with Windows Vista)
One of the great features of LTM is management of volatile or in-memory resource managers.Using the classes/interfaces present in System.Transaction namespace we can make Plain old .NET Objects transaction aware.

The first important class to take note of is the Transaction.It contains methods used for implementing resource managers for enlistment. It also provides functionalities for cloning a transaction and controlling the current transaction context. We can get current transaction, if one is set, using the static Current property.
      tx = Transaction.Current;
            if (tx != null)
            {
               ….
            }
As we have seen in the earlier post transaction manager communicates with the resource managers.Each resource manager needs to enlist with the transaction manager for a particular transaction.For this the Transaction class provides two methods EnlistVolatile-for volatile resource managers and EnlistDurable for durable resource managers.
For custom resource managers to enlist in the transaction they have to implement the IEnlistmentNotification interface.This interface defines the contract that a resource manager should implement to provide two phase commit notification callbacks for the transaction manager upon enlisting for participation.
This interface specifies the following methods:
      
 This callback is invoked during the second phase of a transaction if the transaction is commited.
        public void Commit(Enlistment enlistment)
        {
            ….
        }
 This callback is invoked during the second phase of a transaction if the transaction is in doubt.
        public void InDoubt(Enlistment enlistment)
        {
            …
.
        }
 This notification method is invoked in the first phase when the transaction manager asks participants whether they can commit the transaction.

        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            …
        }
 This callback is invoked during the second phase of a transaction if the transaction is aborted.
        public void Rollback(Enlistment enlistment)
        {
           …
        }

    }
Another important class in TransactionScope.This class is used for marking a code block transactional.On instanting the TransactionScope the transaction manager which transaction to participate.This is guided by the TransactionScopeOption parameter.The ambient transaction is the transaction in whichcode executes.A reference to the ambient transaction can be obtained by Current property of the Transaction class.
If no exception occurs within the transaction scope (that is, between the initialization of the TransactionScope object and the calling of its Dispose method), then the transaction in which the scope participates is allowed to proceed. If an exception does occur within the transaction scope, the transaction in which it participates will be rolled back.When code completes all tasks the Complete method has to be called to inform that transaction manager that it is acceptable to commit the transaction. If this method is not called then transaction is aborted.

The following classes shows the sample and simple implementation of a transaction aware Hashtable:

   class TransactionHashtable
    {
        private Hashtable ht = null;
        private Transaction tx;
        private bool enListed = false;
        public TransactionHashtable()
        {
            ht = new Hashtable();
        }
        public void Add(object key, object value)
        {
            tx = Transaction.Current;
            if (tx != null)
            {
                if (!enListed)
                {
                    tx.EnlistVolatile(new HashtableEnlistor(ref ht), EnlistmentOptions.None);
                    enListed = true;
                }
            }
          
            ht.Add(key, value);
        }
        public IDictionaryEnumerator GetEnumerator()
        {
            return ht.GetEnumerator();
        }
    }

    class HashtableEnlistor : IEnlistmentNotification
    {
        Hashtable ht = null;
        Hashtable htOld = null;
        public HashtableEnlistor(ref Hashtable ht)
        {
            this.ht = ht;
            MemoryStream ms = new MemoryStream();
           
            IFormatter f = new BinaryFormatter();
            f.Serialize(ms, ht);
            ms.Position = 0;
            htOld = (Hashtable)f.Deserialize(ms);
        }
        #region IEnlistmentNotification Members

        public void Commit(Enlistment enlistment)
        {
            enlistment.Done();
        }

        public void InDoubt(Enlistment enlistment)
        {
            throw new NotImplementedException();
        }

        public void Prepare(PreparingEnlistment preparingEnlistment)
        {
            preparingEnlistment.Prepared();
        }

        public void Rollback(Enlistment enlistment)
        {
            ht.Clear();
            IDictionaryEnumerator en = htOld.GetEnumerator();
            while (en.MoveNext())
            {
                ht.Add(en.Key,en.Value);
            }
            enlistment.Done();
        }

        #endregion
    }