Two of the important configuration settings in WCF refer to InstanceContextMode and ConcurrencyMode. These two are very important to control the system resources in your live service. The first (InstanceContextMode) controls the number of instances for your service.
In this case you have three options:
Single - Creates only one service instance in the system.
PerSession (default value) – Create a new service instance per session.
PerCall – Creates a new service instance per call.
The second (ConcurrencyMode) controls how many threads can be run in the service at the same time.
For this configuration we have several options:
Single – Single thread, only one thread in the entire service. You are in thread safe situation; don't worry about protecting your data, synchronization and etc. But in case your service is processing a request, all other request will wait (or failed on request timeout).
Reentrant – This is a tricky one, its means that only one thread can be executed in the service but in case you call to another service the WCF infrastructure will release the lock from it (and then you should protect your service state like in the Multiple mode). You should use it to avoid cases of deadlock when two services with a single concurrency mode are calling each other.
Multiple – Multi-thread, multiple threads can be run on the same time. In most cases you will reduce yours client's timeouts. But remember, this is not a magic solution, high number of thread will cost you in a context switch time (I'll cover the "how to control the number of service active threads" issue in one of my next posts).
Everything sounds simple by now, but the combination between the InstanceContextMode and the ConcurrencyMode is the fascinating part. To clarify this issue I summarized all possible combination in the next table:
| Concurrency Mode.Single | Concurrency Mode.Reentrant | Concurrency Mode.Multiple |
| Instance Context Mode. Single | Creates only one instance from the service (singleton) and only one thread can be executed in the service at the same time. Classic case of single thread. | Creates only one instance from the service (singleton), multiple threads can be executed in callback scenarios. | Creates only one instance from the service (singleton), multiple threads can be executed in the service at the same time. Almost without a bottleneck, must handle the synchronization issues. |
| Instance Context Mode. PerSession | Each proxy gets is own instance, but because only one thread can be executed in the service at the same time all other requests will be queued. bottleneck in case of many clients with a lot of calls. | Each proxy gets is own instance, multiple threads can be executed in the service at the same time in callback scenarios, you have to handle synchronization and data safe. | Each proxy gets is own instance, multiple threads can be executed in the service at the same time. You have to handle synchronization and data safe. Overhead in serialized access to shared data. |
| Instance Context Mode. PerCall | Each call gets a new and dedicated service instance (the service ignore the Concurrency mode in this case) Overhead in instance creation for each call. No synchronization issues. |
In our application we chose WCF as a primary communication component. WCF provide several binding protocols and each one of them had its cons and pros. In our system we needed a high performance communication between several servers, it was the reason we used the WCF with NetTcpBinding. If you want to maximize your system utilization and having a better control on your services, you should make some fine tuning in the NetPctBinding. The default configurations for this binding are good for some classic scenarios, but like every other software if you need something more, you should override this default settings. It sounds like a simple task, just copy an existing binding configuration from the net and put it in your application, but actually it is very hard. The complication is caused by some serious reasons: the errors aren’t clear, the documentation is awful and some of the parameters are affected by each other and are also not documented. In my next posts I’ll write about some of this advanced configurations:
- InstanceContextMode and ConcurrencyMode
- Wcf configuration - Throttling settings
During the last few months I had some thoughts about developing a high performance and scalability systems. The idea of designing a complete system which can support almost unlimited traffic is very exciting and challenging. The main goal is to have maximum utilization of the current resources. Furthermore, is having the ability to add another box and to [almost] double the server performance. Each component should have the ability to scale and to work with several copies in different machines at the same time.
In my next posts I decided to focus on some of interesting issues from the architecture design world, like:
- Communication.
- Configuration.
- Performance
- State sharing
and more…