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.