Chapter 22. Cache Management

Table of Contents

1. Cache Activation and Deactivation
2. Cache Manipulation and cacheItem class

This chapter briefly describes Biferno's cache, i.e. the mechanism used by Biferno to store in RAM requested pages to speed up their execution.

1. Cache Activation and Deactivation

The cache mechanism can be activated in Biferno at application or at script level. To activate the cache for an application the true value must be assigned to the CACHE configuration variable in the "Biferno.config.bfr" application configuration file. When the application cache is active, all pages belonging to that application are stored in RAM on their first execution. The default value for the CACHE variable is false, which implies that pages are read from disk every time they are requested to the server.

Activating the cache causes the original page not to be fetched from disk after the first request, but rather its copy in RAM to be executed. For this reason it is advisable to activate the cache only after the application development phase is concluded, because otherwise modifications to a page on disk will not be executed unless the server cache is flushed or Biferno is reloaded (see Chapter 9, Applications and Variable Scope).

To activate the cache for a single script, the cache property of the curFile class is used. By modifying this property at the beginning of a script, the script itself will be cached even when the cache is disabled at the application level. An example is:

<?
     curFile.cache = true
     // … the rest of the script code follows
?>
    

When the application cache is active, but we do not want that a particular script be cached, we can insert at the beginning of the script the following line:

<?
     curFile.cache = false
     // … the rest of the script code follows
?>
    

To verify if the application cache is active we can either directly check the value of the CACHE configuration variable. An example is:

<?
     // The variable exists and is true
     if (curScript.ValueOf("application CACHE"))
       curFile.cache = false
?>
    

The curFile.fromCache property returns true if the current page was in cache at execution time, false otherwise.

2. Cache Manipulation and cacheItem class

The Biferno cache can be manipulated using properties and methods of the cacheItem class. The cacheItem class describes an element of the Biferno cache, which can be either a script contained in a file with ".bfr" extension that has been previously requested to the server by a client, or a file requested by an include instruction.

Using properties of this class it is possible to obtain information on the file, such as the number of users "connected" to the target Web page at a certain time, how many times the page was requested (total number of hits), date and time of the last request, the time used by the server for page processing, etc.

Using the Flush method of the cacheItem class a single page can be removed from cache, making sure the next client request for the page will force the server to load the page again from its original location on disk.

To completely flush an application cache we can call the curApp.Flush method. The cacheItem class is an extension of the file class, and therefore and object of the cacheItem class has all members (properties and methods) of the file class.

The following script provides an example of the use of the properties of the cacheItem class. In the script the state of the cache of the current application is checked and, for every page stored, all values of the properties of the corresponding cacheItem class object are printed.

<?
	curFile.cache = false
?>
<html>
	<body bgcolor="#ffffff">
		<p>Current application: $application APPLICATION_NAME$</p>
		<p>Cache active? $application CACHE ? 'YES' : 'NO'$</p>
<?
	cacheSize = curApp.cacheTotSize
	cachedPages = curApp.cacheItems
	nPages = cachedPages.dim
	if (nPages)
		{
?>
		<p>Number of pages in cache: $nPages$</p>
		<table bgcolor="#eeeeee" cellspacing="0" cellpadding="2">
<?
			for (i = 1; i <= nPages; i++)
				{
					phys_path = cachedPages[i].path
					user_path = cachedPages[i].userPath
?>
			<tr bgcolor="#dddddd"><td>$i$.</td>
			<td>Page:</td><td>$phys_path$</td></tr>
<?
					if (phys_path != user_path)
						{
?>
			<tr bgcolor="#dddddd"><td></td>
			<td>Requested path:</td><td>$user_path$</td><<tr>
<?
						}
?>
			<tr><td></td><td>Current users:</td>
			<td>$cachedPages[i].currentUsers$</td></tr>
			<tr><td></td><td>Total accesses:</td>
			<td>$cachedPages[i].hits$</td></tr>
			<tr><td></td><td>Date last access:</td>
			<td>$cachedPages[i].lastAccess$</td></tr>
			<tr><td></td><td>Exec. time last access:</td>
			<td>$cachedPages[i].lastExecTime$ millisec.</td></tr>
			<tr><td></td><td>Max exec. time:</td>
			<td>$cachedPages[i].maxExecTime$ millisec.</td></tr>
			<tr><td></td><td>Min exec. time:</td>
			<td>$cachedPages[i].minExecTime$ millisec.</td></tr>
			<tr><td></td><td>Total  exec. time:</td>
			<td>$cachedPages[i].totExecTime$ millisec.</td></tr>
<?
				}
?>
		</table>
		<p>Total cache size: $cacheSize$ byte</p>
<?
		}
	else
?>
		<p>The cache is empty</p>
	</body>
</html>
    

At the start of the script the value of the curFile.cache property is set to false to exclude the script itself from the cache, then the name of the current application and the cache activation state are printed. To analyze the cache content the property:

curApp.cacheItems
    

is used, that returns an array of objects of the cacheItem class that describe the pages stored in the cache and:

curApp.cacheTotSize
    

that returns the total cache size (in bytes).

If the application cache is not empty, the script display a HTML table containing, for every page stored in the cache, the information returned in the corresponding element of the array returned by the curApp.cacheItems property, producing an output similar to the following:

Current application: MyApplication
Cache active? YES
Number of pages in cache: 2
1.	Page:	file://HD/Internet/Web pages/mysite/index.bfr
	Requested path:	file://HD/WebSTAR Server Suite 4.4/mysite/index.bfr
	Current users:	0
	Total accesses:	10
	Date last access:	27-11-2001 11:54:18
	Exec. time last access:	54 millisec.
	Max exec. time:	54 millisec.
	Min exec. time:	1 millisec.
	Total exec. time:	65 millisec.
2.	Page:	file://HD/Internet/Web pages/mysite/home.bfr
	Requested path:	file://HD/WebSTAR Server Suite 4.4/mysite/home.bfr
	Current users:	0
	Total accesses:	3
	Date last access:	27-11-2001 11:43:32
	Exec. time last access:	1 millisec.
	Max exec. time:	1 millisec.
	Min exec. time:	0 millisec.
	Total exec. time:	2 millisec.
Total cache size: 7701 byte
    

Let's now review the meaning of the properties of the cacheItem class.

The userPath property contains the path of the file as requested to the server, which can differ from the physical file path if it contains aliases. In the example the first path is the physical file path, the second path is the requested path (where "mysite" is an alias for the root directory of the Web server).

The currentUsers property contains the total number of users that are simultaneously accessing the page.

The hits property contains the total number of accesses (requests) to the page.

The lastAccess property of the time class contains date and time of the last access to the page.

The lastExecTime, maxExecTime, minExecTime and totExecTime contain, respectively, the time in milliseconds of the last page execution and the maximum, minimum and total (sum for all accesses) page execution time.

Because these values are reset every time Biferno's cache is flushed or Biferno itself is reloaded (see Chapter 9, Applications and Variable Scope), they can not used for web site statistic analysis purposes. They rather supply a snapshot indication of script performances and Biferno load. To obtain web site statistics we advise to use the web server logs in conjunction with a web log analyzer (as the Analog software).

How To Compute Script Execution Time

The time.Millisecs predefined method allows to calculate the execution time of a Biferno script. This method returns an integer value (of the unsigned class) representing the number of milliseconds since the server was started.

Calling this function when the script begins and ends the execution time in milliseconds is easily derived as the difference of the two values returned.