views:

66

answers:

1

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?

+2  A: 

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();
}
theburningmonk
Note that it will introduce a single point of failure.
Dercsár