We have an ASP.net (2.0) application configured to run with multiple worker processes using the web garden option in IIS. Most of our data is cached and occasionally we have to clear the cache when there are changes to the site. We have a simple page that will iterate through the HttpCache items and clear them.
But each worker process has its own copy of the HttpCache object and so when we request for the cache refresh page, it only clears the cache for the process which services that particular request. The cache for the other worker processes are not cleared.
Is there a way to clear the HttpCache for all the worker processes other than programmatically recycling the app pool?
I think in the following post nicholas did explain the same scenario. Please go thgrough it asp.net 2.0 cache api will not work for web garden. You have do some third party caching mechanism.
http://nicholas.piasecki.name/blog/2009/02/on-web-gardens-aspnet-and-iis-60/
Another good discussion about cache in web garden is the following: http://forums.asp.net/p/1077042/1588690.aspx
Hope this will slove your query.
I did it using jquery and an output page that would return the PID of the process that was cleared. It is hard coded to remove from 4 worker processes and not try more than 10 times, usually it gets it in 4 straight tries.
function RemoveFromCache(buttonname, cachename) {
var allprocesses = new Array();
var trynumber = 1;
RemoveOneItem(buttonname, cachename, allprocesses, trynumber);
}
function RemoveOneItem(buttonname, cachename, allprocesses, trynumber) {
var jqxhr = $.get('/admin/cacheitems.aspx', { CacheName: cachename },
function(data) {
if (allprocesses.length == 0) {
$("#" + buttonname).attr('value', data);
allprocesses.push(data);
} else if (allprocesses.length < 4) {
var i=0;
var found = false;
for (i = 0; i < allprocesses.length; i++) {
if (allprocesses[i] == data) {
found = true;
}
}
if (found == false) {
$("#" + buttonname).attr('value', $("#" + buttonname).attr('value') + ',' + data);
allprocesses.push(data);
}
}
if (trynumber < 10) {
if (allprocesses.length < 4) {
trynumber++;
//this slows it down so it can hit a different process
$("#" + buttonname).delay(1000);
RemoveOneItem(buttonname, cachename, allprocesses, trynumber);
} else {
$("#" + buttonname).attr('value', $("#" + buttonname).attr('value') + ',REMOVED');
}
} else {
$("#" + buttonname).attr('value', $("#" + buttonname).attr('value') + ',INCOMPLETE');
}
}
);
}
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack = False Then
If Not IsNothing(Request.QueryString("CacheName")) Then
RemoveFromCache(Request.QueryString("CacheName"))
Else
Load_Data()
End If
End If
End Sub
Sub RemoveFromCache(ByVal CacheName As String)
HttpContext.Current.Cache.Remove(CacheName)
Dim encBytes As New System.Text.UTF8Encoding()
Dim bArray() As Byte = encBytes.GetBytes(CStr(System.Diagnostics.Process.GetCurrentProcess().Id))
Response.Clear()
Response.ContentType = "text/plain"
Response.AddHeader("Content-Length", SharedCode.GetField(bArray.Length))
Response.BinaryWrite(bArray)
Response.End()
End Sub
Protected Sub dgCacheItems_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dgCacheItems.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim drv As DataRowView = CType(e.Item.DataItem, DataRowView)
Dim btn As Button = CType(e.Item.FindControl("btnRemove"), Button)
btn.Attributes("title") = "Remove " & CStr(drv("ItemName"))
'btn.CommandName = "Remove"
'btn.CommandArgument = CStr(drv("ItemName"))
btn.OnClientClick = "RemoveFromCache('" & btn.ClientID & "','" & CStr(drv("ItemName")) & "'); return false;"
End If
End Sub
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