Showing posts with label Windows Communication Foundation. Show all posts
Showing posts with label Windows Communication Foundation. Show all posts

Wednesday, February 11, 2009

WCF Throttling Behaviors and concurrency modes

I am working in a team which is responsible for creating & maintaining enterprise WCF services which are consumed by different clients in an intranet environment. We built well architected WCF services and tested them using our own web client. Everything looked pretty for a while. We threw open the services for enterprise wide intranet clients to consume hoping they'll have the same good time as we had.

But, issues started to see light as different clients began to hit our services. Major complaint is timeout exception. After digging deep, we found is WCF service stops responding after a certain set of client messages. Initially, WCF responded well. All of a sudden, it stops responding. What's happening? Anyways, we found the issue. It's all about sessions which are created for every request. After 10th request, WCF runtime reaches threshold value for maximum number of sessions which results in Timeout exception being thrown out. Then, how can we overcome this issue? There comes to our rescue the WCF runtime throttling properties. Let's see what they're and how they're used.

In a real world, WCF services can experience many issues like Denial of Service attacks, performance problems, over consumption of resources, scalability problems and many more..

For example, Imagine a scenario, where client application starts avalanche series of requests to service using multithreading apparatus or invoking all one-way operations on service which will quickly inaundate service with client requests. How can we handle this situation?

Yes, You can use WCF runtime service throttling properties to prevent over consumption of resources. Reader quotas also come to our rescue in controlling amount of data being transferred between client and service. By engaging throttling, WCF infrastructure precisely controls the number of incoming requests so that the service will be able to handle them effectively with out becoming unavailable.

By default, the ServiceThrottle property of the ChannelDispatcher object is null and the WCF runtime uses its own default values for throttling behavior. To control scalability, you should arrange for the WCF runtime to create a ServiceThrottle object and explicitly set it's properties to values suitable for your environment, taking into account the expected number of concurrent client applications and the work that they are likely to perform.

There are three properties which can be configured under ServiceThrottlingBehavior section of configuration file. You can perform this task in code by creating a ServiceThrottlingBehavior object and setting properties.

MaxConcurrentCalls: The MaxConcurrentCalls setting specifies the number of concurrent messages the service host will accept. Default value is 16 calls.

MaxConcurrentSessions: This property specifies the number of concurrent session-aware channels the service will accept. Default value is 10 concurrent sessions. Long running sessions can cause other clients to block resulting in a time-out.

MaxConcurrentInstances: This property specifies the maximum number of concurrent service instances that the service host will allow. The default value is Int32.MaxValue. The impact this value will have depends on the instance context mode. if the instance context mode is perCall, this will be same as MaxConcurrentCalls property since each call will get it's own instance. if the instance context mode is perSession, this will be same as MaxConcurrentSessions property. If the instance context mode is single, the value of this property will always be 1
When throttling limits are reached, WCF runtime will throw an time out exception irrespective of which property limits are reached.

We can use above defined properties to manage WCF runtime behavior based on our environments and volume of client calls. Exercise caution when overriding default values for this properties for they can have a drastic effect on response times and throughput. For example, clients blocked by limits that are set too low can result in excessive time out errors occuring in client applications.

When throttling is enabled, WCF will check the current counters for each request that arrives. If counters are exceeded, WCF automatically places the request in a queue. When counters come down below the threshold, the requests are then retrieved from queue in the same order for processing.


Concurrency Modes:

Apart from this properties, We can also utilize other attributes to improve scalability of WCF runtime. One of them is Concurrency Mode. If client is running in a asynchronous mode, service can then limit the client to a single thread by setting ConcurrencyMode property of service to single. This property ensures service will process requests in a serial manner one at a time.

Setting ConcurrencyMode to multiple will enable service object to process multiple requests simultaneously.

Setting ConcurrencyMode to reentrant will allow thread to leave the service object and reenter the object at a later point in time.

WCF 3.5 Message Contracts

From practical usage stand point, I've rarely used WCF Message Contracts. My work a lot of time revolved around Data Contracts and Service Contracts. I feel using Message Contracts are limited in their usage except for passing around few custom headers. But, they might be of great help for other folks around. so, let's see what is a message contract?

Defining message contracts lets you gain control over entire SOAP message and NOT just over the structure of data in the body as case with data contracts. Message Contracts deal with accessing and supplying custom headers and lets you define your own message structure.

There's no partial usage of message contracts. After you introduce a message contract into an operation signature, you must use a message contract as the only parameter type and as return type of the operation instead of any data contract for parameters or return type.

Windows Commuication Foundation(WCF) Data Contract serialization techniques

WCF 3.5 supports two types of serialization techniques.
  • DataContractSerializer
  • XmlSerializer

DataContractSerializer Vs XMLSerializer

In contrast to predecessor XmlSerializer, DataContractSerializer serializes only members declared explicitly using DataMember attribute. XmlSerializer serializes all members of data contract except for members declared explicitly using NotSerialized attribute.

WCF Serialization Caveats:

.Net Built-in collection types and custom collections implementing IEnumerable or IEnumerable interfaces are represented as Arrays type when serialized across wire which means they appear as arrays to the clients.

To serialize a custom collection defined in data contract, few things we need to understand are:

  • Collection in the contract must be a concrete collection(not an interface) and is serializable
  • Collection should contain an Add operation

if we satisfy above requirements, WCF automatically serialize the collection as an array of collection's type.

If your collection doesn't meet above requirements, there's a still way to serialize the collections using CollectionDataContractAttribute. You can use this attribute to annotate your custom collections and resulting collections will always be exposed as List collection to it's WCF consumers.

As mentioned in my earlier post, Data Contracts doesn't support inheritance hierarchy. we have to explicitly annotate derived classes with DataContract attribute. Let's know something more about another important attribute in this context.

KnownTypeAttribute:

For instance, we have a derived class called car derived from base class called vehicle. When you pass in a car object instead of vehicle object, the service doesn't know how to deserialize the car object it received, because it doesn't know about car object.

Much the same way, when a car object is returned instead of a vehicle, the client doesn't know how to deserialize it, because all it about are vehicles but not cars.

The solution is to explicitly tell WCF about the car class using the KnownTypeAttribute attribute. The KnownType attribute allows you to designate sub classes for the data contract of base class.

Polymorphism is outside the paradigm of Service orientation. So, KnownTypeAttribute is required to specify derived class relationship with base class for DataContract Serializer.

We've to annotate base class with KnownTypeAttribute for all those derived classes being utilized in the data contract.