Home cooked web monitoring use Rx

One of the key things in software is to write succinct , declarative and asynchronous code. The answer to that is Reactive Extensions for .NET 

I have been digging into Rx for sometime now. Though there isn’t much of documentation I have been kind of successful in getting certain things done with it.

One of requirement that came up from our Operations was to monitor some websites and notify someone if the site was not accessible. But the added constraints to this were check for the site status only at a certain interval and report failure only if it was more than certain percentage within a certain duration.

So it was like check the site status every 5 seconds , buffer the results for a minute and in the buffered response if it had more 3  failures then tweet someone about it.

And here is the code to solve the problem

 (from time in Observable.Interval(TimeSpan.FromSeconds(5))
 let req = WebRequest.Create("http://www.nonexisting.com")
 from res in Observable.
    FromAsyncPattern<WebResponse>(
        req.BeginGetResponse, req.EndGetResponse)()
 .Materialize()select res).Buffer(new TimeSpan(0, 0, 1, 0)).
    Select(failed => 
        failed.Where(
        n => n.Kind == NotificationKind.OnError)).
    Where(failed => failed.Count() > 3).
    Subscribe(x => Tweet("Nonexisting.com Failed thrice"));
Console.Read();

The “from time in Observable.Interval(TimeSpan.FromSeconds(5)” is for ensuring that an Observable is generated every 5 seconds to check the status of the website. In the next line the code creates a web request.

Using the FromAsyncPattern I was able to reduce all the plumbing code to handle async i/o calls for the web request.  The materialize is for the sequence to continue even if there is an exception. Here is an good write up on Materialize. And the rest is just the usual Linq where the code filters Notification type of error.

This was a fun exercise. I will continue to explore Rx and blog about it.