This article describes a process for using a ThreadPool within a windows service that monitors other services. It also shows how to allow multithreaded read/write access to an XmlDocument, that acts as persistent storage, using a Mutex.
Summary
This article describes a process for using a ThreadPool within a windows service that monitors other services. It also shows how to allow multithreaded read/write access to an XmlDocument, that acts as persistent storage, using a Mutex. The windows services that I'm monitoring here just happen to be web applications based on a Java application server. So, what I do is check a page running within the service to see if (a) it doesn't timeout or (b) doesn't match the text that it expects to see. If that is the case, I assume the service is down, or in an error state and I restart the service.
ServiceController oSC;oSC =
I can then do a
oSC.Start(); The Monitor
My input XML file, called focus.xml, looks like this:
<?
The key here is that each server can have multiple services that I monitor. I read this XmlDocument and in a loop, call the Http monitoring service, passing in the text of the Name, Webpage and Verify text nodes. Retries is the number I increment if there is a timeout. What I do is set the the service on a 5 minute polling interval and on the second retry, I restart the service. I pass all these parameters in as a delimited string, because a ThreadPool callback function can only take 1 parameter ( I suppose I could use a string[] as well ! ). The service uses a Timer that runs on a 5 minute interval and runs this code:while (reader.Read()) {if (reader.Name.Equals("name") && reader.NodeType == XmlNodeType.Element) {sight += reader.ReadElementString("name") + "|";//Debug.WriteLine(sight);}if (reader.Name.Equals("webpage") && reader.NodeType ==XmlNodeType.Element) {sight += reader.ReadElementString("webpage") + "|";//Debug.WriteLine(sight);}if (reader.Name.Equals("verify") && reader.NodeType ==XmlNodeType.Element) {sight += reader.ReadElementString("verify");Debug.WriteLine(sight);ThreadPool.QueueUserWorkItem (new WaitCallback (VerifyHttpService), sight);sight = "";}}
A ThreadPool is nice for threads that are relatively homogeneous. It is a nice simple structure and is available with out instantiation as a static class.
Http Monitor
Now lets look at the Http monitor. In the VerifyHttpService method I split the string into its components.
iTest =PathEval.pathXeval(getPath() + @"\focus.xml", @"/network/server/service[name='" +retina[0] +"']/retries");
This query can both read and update the XmlDocument. If there is a timeout, and RETRIES is 0, then it increments it to 1. If it's one, it sets it back to 0 ( because 1 means it's going to restart the service ). But remember, there can be multiple services on the server and hence multiple threads writing to the XmlDocument! And these threads are going to be attacking the XmlDocument all in the same millesecond!
How do we handle this? With a Mutex of course! A mutex acts as a queue that pools up the requests so there is no collision! So the PathEval.pathXeval() method looks like:
...
So the Mutex lets me use an XmlDocument as a mini-database!
Next Steps
Next project will be for me to create a web service with a global XmlDocument to be a simple data store that can be updated and read by multiple client web service consumers!
Pro WPF: Windows Presentation Foundation in .NET 3.0