I have a WCF service load balanced across three different machines.
Let's say these services can process requests of types A, B, and C. There are no limits to processing A or B. However, we can only process 5 requests of type C at a time, so if a 6th request of type C comes in, it'll have to wait until one of the previous requests finish.
How can I make sure that only 5 requests of type C are being processed across all three machines?
WCF service can handle one request at a time.
Throttling controls place limits on the number of concurrent calls, instances, or sessions to prevent over-consumption of resources. Throttling behavior is specified in service configuration file settings. This sample is based on the Getting Started that implements a calculator service.
There are three types of hosting environments for WCF services: IIS, WAS, and self-hosting. The term “self-hosting” refers to any application that provides its own code to initialize the hosting environment. This includes console, Windows Forms, WPF, and managed Windows services.
Sounds like you need a cross-machine semaphore, you can implement one using a distributed caching solution like memcached. Alternatively you could have another WCF service running on a single machine which manages the semaphore for your load balanced services.
So the new service might look something like this:
[ServiceContract]
public interface ISemaphorService
{
[OperationContract]
void Acquire();
[OperationContract]
void Release();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class SemaphoreService
{
private readonly static Semaphore Pool = new Semaphore(5, 5);
public void Acquire()
{
Pool.WaitOne();
}
public void Release()
{
Pool.Release();
}
}
In a real world app you might want to have the number of semaphores configurable in a config or something and put in some timeouts and putting in mechanism to make sure semaphores are released in a timely fashion and/or when the client crashes:
// on the client side (service C)
var client = new SemaphoreServiceClient();
try
{
// acquire the semaphore before processing the request
client.Acquire();
// process request
...
}
finally
{
// always remember the release the semaphore
client.Release();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With