How to share a Semaphore across 2 w3wp.exe IIS processes

414 views Asked by At

How do I create a semaphore that is accessible across 2 separate w3wp.exe processes on Azure. The problem on Azure is that when a new application configuration item is added Azure restarts my website on a new w3wp.exe process that is running concurrently with the old w3wp.exe process while it is shutting down. I use a semaphore to synchronize between the 2. This has worked well up until now i.e. On local IIS - config changes normally just start a new app domain, but on Azure a new w3wp.exe process is started. And this new process does not recognise an existing named semaphore.

The following code always indicates the semaphore does not exist. Even when I create a standalone console app and create the semaphore - I still get it does not exist in my web app. There seems to be a namespace in play for semaphores in IIS on Azure. I had seen another post on an early version of IIS that semaphores only became globally shared across processes if they had "Global\" as a name prefix - this does not work on Azure and I can't find out what the "global" namespace should be - any ideas?

FYI - If I run a console application - 2 instances - that both access the same semaphore they can both see it. But 2 processes running in IIS on Azure cannot.

try
{
    // Open the semaphore 
    //
    _semaphore2 = Semaphore.OpenExisting(name);
    doesNotExist = false;
}
catch (WaitHandleCannotBeOpenedException)
{
    _logger.Info<MainDom>("Semaphore ({name}) does not exist", name);
    doesNotExist = true;
}
2

There are 2 answers

14
Architect Jamie On

The behavior of spawning a new worker process is called overlapped recycling. You can disable this behavior and allow for the worker process to shut down completely before the new process is started. You can even disable recycling on configuration change.

For local IIS, modify the advanced properties of the app pool and configure the Disable Overlapped Recycle and/or Disable Recycling for Configuration Changes options. I believe the latter is only available in IIS 10+.

Configure Applcation Pool

The process for Azure is a bit trickier. It involves updating the applicationHost.config for which you need to use Kudu. See this thread for detailed instructions.

Essentially, it involves creating an XDT (transform) file to update the config file. An example can be found:

https://github.com/projectkudu/kudu/wiki/Xdt-transform-samples#remove-all-your-recycling-options-from-your-net-4-application-pool-and-make-it-available-always

Edit:

If the above does not prevent two worker processes running concurrently, you may also need to configure the Shutdown Time Limit. In the transform file, include the second line in the following block:

<add name="yourAppPoolNameHere" autoStart="true" managedRuntimeVersion="v4.0">
    <processModel shutdownTimeLimit="00:00:01" />

Word of caution, the above will result in svchost.exe killing the w3wp.exe process after 1 second without any grace.

0
john blair On

This is a workaround - not an answer - but posting it here in case it helps others - as it is buried in one of my comments which is hidden by default.

Setting WEBSITE_DISABLE_OVERLAPPED_RECYCLING to 1 in the Azure Application Settings worked in terms of serializing the w3wp processes i.e. one would shutdown completely before the other started up - in my case this avoided the need for the semaphore. I would still like an answer to the original question.