Microsoft Azure Open Source Development Support Team Blog

Support for Open Source Technologies on Microsoft Azure App Service

Use IIS AppInit Module to Clear Cache on Local Disks for Multiple Instances on Azure Web Apps

A solution to increase PHP Performance for MVC Frameworks (ex: CodeIgniter, Symfony, Laravel, etc.) is to save the cache to local disk. Since the cache is saved locally to the VM, there will be an improved performance boost.

However, this raises a couple of questions:

  1. How can cache be cleared from the local disk?
  2. And if there are multiple instance, how can cache be cleared in each instance?

The local disk can be written to programmatically by the application, but Azure Web Apps does not provide a way to read this easily. It may seem like it does on the SCM site, but the SCM site is in a separate application pool and the local disks are not shared between the pools. Meaning when you access the SCM’s local disk, you are not accessing the Web App’s local disk. So in order to access the web app’s local disk, we have to access it the same way the MVC Frameworks do – programmatically.

Now that we have the answer to question #1, how do we go about answering #2?

Well, the answer is in the title of the blog post. J

IIS has the ability to execute a script on a W3WP process recycle. This includes: restarts, application settings updates, scaling out to new instances, etc. By no means is this a full list. See discussions online to find out more about recycles.

The concept here is to use a script to clear the cache on demand. However, if we link the script to the AppInit module, it will run every time there is a recycle. So to circumvent this running unnecessarily, we can add a Boolean variable which controls whether the cache should be cleared. Makes sense? Good! J

And to take this a step further, let’s keep a log of when the AppInit was triggered and if the cache was cleared.

Alright, let’s get down to the nitty gritty, code level.

This solution has 3 parts:

  1. web.config
  2. Initialization Page (appInit, PHP script)
  3. Application Settings

web.config

Place this in wwwroot directory. This tells IIS to run the script defined in “initializationPage” on recycles. Hostname is the Web App name.

<configuration>
<system.webServer>
 <applicationInitialization doAppInitAfterRestart="true" skipManagedModules="true">
      <add initializationPage="/appInit/maybeCacheClear.php" hostName="mangeshnew.azurewebsites.net"/>
 </applicationInitialization>
 </system.webServer>
</configuration>

Initialization Page (appInit script)

Here is sample code for the appInit script. All you have to do is copy it and insert the script to clear the cache for your particular framework.

<?php

// File Location: wwwroot/appInit/maybeCacheClear.php
/***********************************************
 This script runs when the web app is recycled.
 ***********************************************
 
 You can lock the cache in two ways so it is not cleared on a recycle:
 
 1) add the application setting 'cacheLock' and set the value to true
 2) create a file, cache.lock, within this directory
 
*************************************************************************/


if ( file_exists('cache.lock') || ("true" == strtolower(getenv('cacheLock'))) )
{
 $message = "================================\n"
 . 'Time Stamp: '. date('m/d/Y H:i:s') ."\n"
 . "--------------------------------\n"
 . "Cache is locked. Cannot clear cache.\n"
 . 'Computer Name: ' .$_SERVER['COMPUTERNAME'] ."\n"
 . 'Instance ID: ' . $_SERVER['WEBSITE_INSTANCE_ID'] . "\n\n"; 
}
else
{
 //!!CLEAR THE CACHE!!
 //<INSERT CODE HERE TO CLEAR CACHE>
 
 $message = "================================\n"
 . 'Time Stamp: '. date('m/d/Y H:i:s') ."\n"
 . "--------------------------------\n"
 . "*** CLEARING CACHE***\n"
 . 'Computer Name: ' .$_SERVER['COMPUTERNAME'] ."\n"
 . 'Instance ID: ' . $_SERVER['WEBSITE_INSTANCE_ID'] . "\n\n";
}

// Write the contents back to the file
file_put_contents('cache.log', $message, FILE_APPEND);

Application Settings

Add the following application setting and set the value to true.

2016-12-08-19_44_43-application-settings-microsoft-azure

Sample cache.log

Now that all components are in place, trigger a recycle by restarting or updating an Application Setting. If everything went well, we will have a message within cache.log. It should look something like this:

2016-12-08-19_47_05-diagnostic-console