w3wp.exe high cpu usage thread

Yesterday I learned an important lesson about IIS logs. They do not show you all of the requests hitting your server! Evidently the log does not show canceled requests.

Over the last couple of days I was receiving complaints about slow responses from our web site. By the time I would look at the CPU utilization it would be within the normal range. I looked in the IIS log file for timeouts but could not find any. So I ran a two hour trace on Thursday afternoon. Friday morning I crunched the trace with PAL and discovered several unaccountable CPU peaks attributable to w3wp.exe. An Internet search for “w3wp.exe high cpu usage”  led me to this thread in which several people recommended using IISPeek to find the misbehaving request. So I installed a trial version of IISPeek and started watching the transactions coming in. Pretty soon I saw something I was not expecting. A shopping site was coming to our site and trying to retrieve a  product advertising feed. What was surprising was not that the shopping site was retrieving the feed but there was no log of it in the IIS log file.   This request had been consuming our CPU for several minutes and then disappearing without a trace. I knew this query had some serious performance issues but the IIS log indicated that it had been working on previous days. I did not know it was running so often. With IISPeek and Task Manager running together I could see the impact on the site. Evidently this particular shopping site would time out or cancel the query before our site either returned the data or timed out.  It was at this moment that I figured out that IIS must have a “no harm, no foul” policy about canceled queries. My reliance on the IIS log was a mistake in this case. Since this shopping site was not getting the data, the shopping site would try again at a later time. When I was watching it with IISPeek I was seeing this request about every fifteen minutes. Fortunately I had already developed some web page caching code I could implement quickly and get us over this hump. Within an hour the shopping site had its data and our web site was back to normal. I have solved a lot of web site problems by looking at the IIS log but in this case it was not the right tool for the job. On Monday I am buying a copy of IISPeek!

Cleaning up an existing newsletter mailing list

In December 2008 I was asked to clean up some problems with our newsletter at work.  We had over 100,000 people on the mailing list and over 90% of the people on the list have ordered from our website. After a little bit of analysis I determined that we were bouncing 30% of our newsletter emails because we had failed to follow the most basic rules of newsletter management and the automated newsletter cleanup procedures did not work. So here is my list of tasks I used to cleanup the newsletter and get the bounce rate down to 0.1%.   In our case we are sending the emails out from a dedicated server at our office.

  1. Use a static IP to send out the newsletter.  One of the first SPAM checks email providers use is to see whether the  IP you are using to send out the newsletter is coming from your domain.  This means that you need to set up a sub-domain(e.g. mailserver.mycompany.com) and a PTR record for the sub-domain.
    1. Set up a sub-domain for the static IP. Since our web server is hosted we had to ask our host provider to set up the sub-domain.
    2. Set up a PTR record for reverse DNS lookup. I asked the folks who provided us our static IP to set up the PTR record to the sub-domain.
    3. If everything is set up correctly you should be able to pass the reverse DNS lookup test. This is the site, Forward Confirmed Reverse DNS Lookup Test, I used to confirm it was working properly.
  2. Set up feedback loops if you can. Feedback loops are pretty dumb idea that email providers like. I dislike them since I have only feedback loop that is useful. I am grateful that AOL has made it reasonably easy for me to remove people who do not want to be on our mailing list. I was able to quickly modify our existing newsletter template to embed an unsubscribe link that would make it through the feedback loop processing. On the other hand I found I wasted a huge amount of time trying to set up a feedback loop with  Yahoo and Hotmail. Both Yahoo and Gmail  want you to sign your emails with DKIM or they will not talk to you. DKIM was supposed to reduce SPAM but I have not seen any reports showing it reducing SPAM. Implementing DKIM will require me to set up a new email server for the newsletter so it is pretty far down my priority list. So far I have been able to ignore this issue. Hotmail wanted me to get a letter from our local internet provider saying we were the only folks using the static IP. Our local internet provider, RoadRunner, told me several times that no customer had ever requested a letter like that and they were not going to provide it. I set up a feedback loop with Comcast but after a couple of months they increased the amount of information they redacted from the email and broke the unsubscribe loop in the feedback loop message. 
  3. Embed an unsubscribe link in your newsletter template that will unsubscribe the user but does not require the email address.  Since most feedback loops redact the email address, this will allow you click on the link in the Feedback loop message to unsubscribe the user.
  4. Go through the error log on your email server and look for the messages that indicate that email address is inactive or no longer used. Unfortunately there is a multitude of messages that are used to describe unknown users(5.1.1, 5.5.1, unknown user, alias not found).  This is one area that begs for a standard. This is where the feedback loop should have been.
  5. Manually go through your newsletter inbox and look for:
    1. Earthlink, PeoplePC, Zonealert, and other verification replies
    2. Unknown user messages.
    3. Feedback loop messages
    4. Changed addresses and unsubscribe messages.
    5. Other replies.
      1. Mailbox full, Out of office replies
      2. Customer service requests. About once a week we get a reply to the newsletter that asks a question about a product.
      3. Miscellaneous SMTP problems(e.g. DNS and email forwarding problems)

How to remove the Windows.old folder that is generated when you install Windows 7

I am not sure how I got this 2.2 GB folder on my “C”  partition but it was not necessary. With free space on my “C” partition down to 5% it was time to clean house. The Vista instructions will work as written if you run the Disk Cleanup utility as the Administrator. If you happen to run the utility as a “mere mortal” there is a button in the Windows 7 version to restart the utility as an Administrator if you want to “Clean up system files”.

How to remove the Windows.old folder that is generated when you perform a custom installation of Windows Vista

Jeditable and Classic ASP

This week I implemented a grid style application using Classic ASP and Jeditable. The hardest part of implementing this application was trying to figure out what a save.asp version of save.php would look like. Here the template I created.

 
<% 
dim sID, sValue,errorcode dim field1,field2,field3,field4 
'The sID is a spreadsheet style ID 
'As an example B3 would be the second editable field 
'for DB ID field = 3
sID = request("id") 
sValue = request("value") 
sType = mid(sID,1,1) 
sDataID = mid(sID,2)  
'We have four editable fields 
'The changed field will not be null 
field1 = null 
field2 = null 
field3 = null 
field4 = null 
errorcode = 0  
select case sType 
case "A" 	
field1 = sValue 
case "B" 	
field2 = sValue 
case "C" 	
field3 = sValue 
case "D" 	
field4 = sValue 
case else 	
errorcode = 1 
end select 
if errorcode = 0 then 
'Validate and update the data base 
end if 
if errorcode = 0 then 
'Send back the value field 
Response.Write sValue 
else  
Response.Write "<b>!Error " & errorcode & "</b>" 
end if 
%>