Monday, December 31, 2012

2012 Annual Review

It's that time of the year again where I take some time to look back on the year passed and peek at the year ahead. This is mostly a post I like to write up for myself, forcing reflection.

The biggest personal changes this year were moving out of my parents' place, and my girlfriend's decision to study medicine after graduating as a Master of Arts earlier this year. I had no idea how things would turn out once we lived together, but so far we have been doing great.

My career

September marked one year working for Euricom. I'm still at my first client, and while I definitely regularly have my share of the enterprise blues, I also learned a lot working on several projects: from maintaining legacy to leading green fields. Fairly, I often doubt if traditional enterprise life is it for me though.

Blog

I published 66 posts this year, which seems to be consistent with previous years.

While writing has turned into a habit over the years, I often struggle with deciding what I should write about. Any reason is probably a good one though; documenting, sharing opinions and experiences, or just writing for the sake of writing... But I still feel like I should add value and contribute something worthwhile when I spend time on this blog.

The topics haven't changed that much this year. I still write often on Web technologies (ASP.NET, NancyFx and REST) - something I didn't get to spend much time on at work this year, but I also wrote about architecture, testing and NoSQL. Next to those topics, I also penned some of my experiences gained doing experimental side projects.
In 2013, I intent to get more out of my comfort zone, and to also write down thoughts which are not that strongly held.

Page views have more than doubled (173k) compared to 2011, which I'm humbled by, but I seem to care less about that than a little while ago. It had even been over a month since I logged into Google Analytics.


Community

It very much depends on what I'm doing that day, but I still spend quite some time on Twitter. I often blurt out thoughts on software, and regularly, someone who knows better than me replies, and challenges my looks on software. That's how I get value out of Twitter. That, and animated GIFs of course.

In real life, I went to see a few interesting speakers at local user groups, and gave a talk myself at Web.NET Europe Milan - international speaker, wooh. I want to applaud the organization of Web.NET Europe once more; they did a great job.

In general, I started to value artificial sponsored user groups less. They have their place, and they do add value, but it's not something that I feel I need to be a part of. Having some beers with a few likeminded developers suits me better.

Travelling

Buying an apartment and all of that, we didn't get to make any epic travels this year. I got to visit three different countries though: Italy, Tunisia, Italy again, and France. Two out of four were sponsored by my job; not bad.

We're setting out for a big trip again in 2013. We fell in love with America two years ago, so we've been researching the South-West again - but closer to the Mexican border this time. Other destinations are still open for discussion though.

Projects

I spent a considerate part of 2012 building small things on the side. This didn't result in anything useful, but most importantly, it got me in the habit of working on my own things, and I put together a toolset which enables me to ship things fast (NancyFx, Twitter Bootstrap, MongoDB, AppHarbor, ...).

The first project I did in 2012 was Docary. This was supposed to be something between a timesheet and a diary. This idea quickly died after I couldn't commit to using it myself. Technically I played with early versions of jQuery mobile and EF, and learned why you shouldn't overlayer your MVC application - or any web application for the matter.

For the second project, I and Davy Brion worked on TopDevLinks. This was supposed to be a linkblog implementation on top of ASP.NET MVC, CQS and MongoDB. We both lost interest in the concept eventually.

I made my girlfriend a petite portfolio site built on top of NancyFx, the FlickR API, and some jQuery plug-ins. Right now, it's actually running as a static site on GitHub pages though.

I already blogged about the next project: Kill Long Meetings. This one is still around, but quickly floundered into forgetfulness after its five minutes of Twitter fame.

The last two things I worked on this year were my Antwerp Open Data submissions. I jotted down some technical details here. The Nancy.AspNetSprites.Razor package also sprouted out of that effort (almost 100 downloads!).

Now that I look back at it, I did write quite some code after my hours this year... Next to being in the moment of building and shipping stuff, I genuinely believe it makes me better at my job.

I hope to be able to do as much in 2013, but to also let it be something worthwhile. I'll be actually already shipping something new in a few weeks if all goes well.

Sport/Health

The biggest gift I gave myself health wise this year, was giving up on smoking; I lit my last one over six months ago!

Moving to Antwerp, and not having any area to put my weights, I've joined a gym again, where I'm doing a two times a week compound routine. That should make me stronger again; I've lost a lot of beef since picking up running three years ago.

I haven't given up on running - living close to the city park helps. I just missed the 1000km (or 621 miles) milestone this year, which is kind of lame, but I'm far from complaining.


I don't know what I hope for in this area in 2013. It's starting to dawn on me that, even though those goals I set for myself have pushed me further than I thought I was capable of - I couldn't jog 1km without a break three years ago, they are not that important. It eventually comes down to nourishing your body, and making use of it in every way possible while you still can.

Conclusion

Earlier this week, I strolled down the main street of Brussels and crossed a beggar with one leg and no arms. Next to feeling extremely sorry for that man, I felt truly blessed; I'm healthy, loved, have more than I need, and I get to do what I like for a living. I need to remind myself more of that in 2013 - I can be a whiny bitch.

I plan to keep course in 2013, but as a better man.

How was your year? What do you plan for in 2013?

Now, if you'll excuse me, I'm going to help a hand in preparing the festivities before the girlfriend really gets in a faul mood.

Holy crap, when I sat down to write this, I didn't expect to write a whole book. I'm wondering how many people actually made it down here. 

Sunday, December 23, 2012

2012's most read posts

I look forward to writing this post each year; it's by far the easiest one to write, and it provides me with an occasion to look back on previous years (2009, 2010, 2011). It's entertaining - and shameful too - to see what kept me busy back then, which opinions I held, and which technologies and techniques are still relevant in the meanwhile. Anyways, here it goes.

The most read post this year, with 37.797 page views, is How a web application can download and store over 2GB without you even knowing it. I just ran this experiment again with the latest Chrome build, and apparently the Chrome team hasn't addressed these concerns in the meanwhile; the browser still behaves exactly the same. I'm guessing usage stats might prove that it's not worth the effort.

The second most read post, with 14.371 page views, is Learning: the Hacker Way. I still firmly stand by this one today. Passive learning can only take you so far; it's crucial to supplement passive learning with a high volume of getting your hands dirty.

With 14.085 page views, Commuting: have you done the math? comes in third. Commuting wastes a good part of your life; optimizing your commute can significantly improve the quality of your average day. Readers shared some interesting experiences in the comments on this one.

Having 5.215 page views, the post Why I will always love RSS is the penultimate item in this list. This writing is basically a rant on how, although I somewhat understand the motivation behind public companies fencing their gardens, it is sad to see that even peers seem to advertise the death of RSS, while it's RSS that has enabled me to follow my favorite sources of information without having to rely on others to tell me what to read, and without having to be connected the whole damn time.

With 1000 views less, making it the last item in the list, is the post HTML5 Offline Web applications as an afterthought in ASP.NET MVC. It was this post that landed me a paid article on InfoQ. I should revisit this topic again, I'm curious to see how many websites are already making use of this HTML5 super cache to improve performance, or to truly provide offline access.

Thank you for reading in 2012!

Sunday, December 16, 2012

Released: My Antwerp Open Data submissions

A little while ago the city of Antwerp released their Open Data initiative, and it included a meetup where you could show something you built, build something on the spot, or pitch your ideas. When I first heard of the initiative I had nothing going on the side, and was looking for something tangible I could build to try out a few technologies. I couldn't come up with an original idea, and ended up building two web applications using the Open Data datasets: Culture Mosaic, and Where to pee in Antwerp?
Since I was bedridden due to the flu, and my ideas were not that great, I eventually ended up not going to the meetup, but I figured I would share some stuff I picked up along the way here.

Culture Mosaic

The first web application uses the culture dataset to display a masonry of cultural attraction images.


The images available vary in size, and some turned out to be quite large. If I wanted to display all the images at once, I had to make them smaller; resize them. For this task, I found the ImageResizer library on Nuget. Although you can reference remote images using an ImageResizer extension, I chose to download the images locally, to then resize them and to finally cache them on disk.

I run these tasks in parallel and wait for all of them to finish, using the TPL.
private void TryToDownloadAllImages(Culture culture)
{
    var tasks = new List<Task>();

    foreach (var item in culture.Items)
    {
        var localPath = Path.Combine(_pathConfiguration.ImagesFolderPath, item.ImageName);
        if (!File.Exists(localPath))
            tasks.Add(CreateImageDownloadTask(item.Image, localPath));
    }

    Task.WaitAll(tasks.ToArray());     
}
Downloading a remote file is straightforward using the WebClient class. Right after downloading the image, I use the ImageBuilder singleton to resize the image to a width of 340px.
private Task CreateImageDownloadTask(string imageUrl, string localPath)
{
    return Task.Factory.StartNew(() =>
    {
        using (var client = new WebClient())
        {
            try
            {                        
                client.DownloadFile(imageUrl, localPath);

                ImageBuilder.Current.Build(
                    localPath, 
                    localPath, 
                    new ResizeSettings("maxwidth=340"));
            }            
            catch (ArgumentException) 
            {
                // filename malformatted; swallow
            }
        }
    });                    
}                
Now that I have my resized images, I can render them in my view. This is NancyFx with the Razor view engine by the way.
<div id="loading">
    Loading..
</div>      
<div id="container" style="display:none;">
    @foreach (var item in Model.Items)
    {               
       <a href="@item.Url">
          <img src="/Content/images/@item.ImageName" alt="@item.Name" title="@item.Name" />
       </a>             
    }
</div>
To achieve the masonry effect, I used this jQuery plug-in. The one tricky part here is to only initialize the effect after all the images have really loaded. For this, I used the imagesLoaded plug-in. 
$container.imagesLoaded(function () {
    $loading.hide();
    $container.show();
    $container.masonry({
        itemSelector: 'img'
    });
});
One last thing I wanted, was to center the masonry on screen, but since I didn't want to use a fixed width, I had to dynamically recalculate the optimal width each time the window is resized. 
var setContainerWidth = function (container) {
    var imageWidth = 340;
    var bodyWidth = $("body").width();

    var numberOfImagesNextToEachother = Math.floor(bodyWidth / imageWidth);
    var optimalWidth = (imageWidth * numberOfImagesNextToEachother) + (numberOfImagesNextToEachother * 4);

    container.css("width", optimalWidth + "px");
};

$(window).resize(function () {
    setContainerWidth($container);
});
Since we have the width of the images (340px), we can use trivial math to calculate the optimal amount of width we can consume.

You can find the working bits on AppHarbor. Source is on GitHub.

Where to pee in Antwerp?

The next application is a mobile web application that uses the public toilets dataset to show the nearest toilets based on your location.


I wanted to introduce a constraint client-side of having to work with a somewhat crooked dataset, that's why I just return the dataset using Nancy as is.
public ToiletsModule()
{
    Get["/Toilets"] = p =>
    {
        var response = Response.AsFile(@"Content\json\toilets.json");
        response.ContentType = "application/json";

        return response;
    };
}
At the client, I'm using jQuery Mobile and angular.js. It had been a while since I had done something with jQuery Mobile, but this version felt very solid (compared to the beta versions I played with before). Turns out though, that to make jQuery Mobile and angular.js play nice, you have to include the jQuery Mobile Angular adapter. The size of all these libraries unminified was a performance hog; Cassette to the rescue.

The first thing you do with angular, is defining a module. A module instantiates, wires and bootstraps the application.
var toiletApp = { };        
toiletApp.module = angular.module('toiletModule', []);
To separate concerns, and make things testable, angular lets you define services for your application using a factory. By using a factory you also make your service an injectable dependency for other parts of your application.
I added a toilet service to this module which makes the ajax call, sorts the results based on nearest by, to eventually make them available to the caller by invoking a callback. The $http dependency is one of angular's core services that lets you do ajax requests.
toiletApp.module.factory('toiletService', function ($http, Toilet) {

return {

    getToilets: function (onSucess, onError, coordinates) {

        $http
            .get('toilets')
            .success(function (data) {

                var toilets = [];

                for (var i = 0; i < data.openbaartoilet.length; i++) {
                    var toilet = data.openbaartoilet[i];

                    var ourToilet = new Toilet(
                        toilet.omschrijving,
                        toilet.point_lat,
                        toilet.point_lng,
                        toilet.betalend === "niet betalend" ? false : true,
                        toilet.straat,
                        toilet.huisnummer);

                    toilets.push(ourToilet);
                }

                if (coordinates) {

                    toilets.sort(function (a, b) {
                        var aDistance = a.calculateDistance(coordinates);
                        var bDistance = b.calculateDistance(coordinates);

                        if (aDistance < bDistance)
                            return -1;
                        if (aDistance > bDistance)
                            return 1;
                        return 0;
                    });

                }

                onSucess(toilets);
            })
            .error(function() { onError() });

    }

};
You might have noticed the Toilet dependency; into this class I project the items returned from the ajax call.
toiletApp.module.factory('Toilet', function () {               

var Toilet = function (name, lat, lng, isPaying, street, houseNumber) {
    var lastCalculatedCoord;
    var lastCalculatedDistance;

    this.name = name;
    this.latitude = lat;
    this.longitude = lng;
    this.isPaying = isPaying;
    this.street = street;
    this.houseNumber = houseNumber;
    this.lastCalculatedDistance = function () {
        return lastCalculatedDistance;
    };
    this.calculateDistance = function (coordinates) {
        if (coordinates) {
            if (lastCalculatedCoord == coordinates) {
                return lastCalculatedDistance;
            }

            var currentPosLatLon = new LatLon(coordinates.latitude, coordinates.longitude);
            var destinationPosLatLon = new LatLon(this.latitude, this.longitude);
            var dist = Math.ceil(currentPosLatLon.distanceTo(destinationPosLatLon) * 1000);

            lastCalculatedCoord = coordinates;
            lastCalculatedDistance = dist;

            return lastCalculatedDistance;
        }
        return null;
    };
    this.getMapUrl = function () {
        var coord = this.latitude + "," + this.longitude;

        return "...";
    };
};
The Toilet class also has a method to calculate the distance from the item to any given coordinate. I first wanted to make use of the Google Distance Matrix API to calculate the actual travel distance, but that didn't really work out to well for more than 100 items; you can't batch your requests, and the free version of the API has a threshold on the amount of queries. I turned to calculating the great-circle distance instead, using this library.

Since we want to make use of the client's coordinates, I also defined a geo service, which makes use of the HTML5 GeoLocation API to query for the user's coordinates.
toiletApp.module.factory('geoService', function() {

    return {

        getLocation: function (onSucess, onError, onNotAllowed) {
            if (navigator.geolocation) {

                navigator.geolocation.getCurrentPosition(

                    function (position) {
                        onSucess(position);
                    },

                    function (err) {
                        onError(err);
                    }

                );

            } else {
                onNotAllowed(message);
            }
        }

    };

});
After defining these pieces, I injected them into the ContentController. The controller is responsible for augmenting angular's scope, which is the connection to our view, our model. Properties and methods are made available to the view by augmenting the $scope variable. There is quite some not that interesting tinkering going on in the controller, so I left it out for brevity.
toiletApp.ContentController = function ($scope, geoService, toiletService) {
    $scope.toilets = [];
    ...
}
After setting ng-app and ng-controller, we can make use of angular's directives and filters to render our page. Directives are - as the documentation puts it - a way to teach HTML new tricks. Think of it as HTML helpers. Filters are used to format data.

The view binds each toilet to a new collapsible div. The content of the div shows some basic information, and a button which shows the toilet on a map.
<html ng-app="toiletModule">
    <head>
        ....
    </head>
    <body>
        <div data-role="page" id="home" ng-controller="toiletApp.ContentController"> 
            
            <div data-role="header">
                <h1>Where to pee in Antwerp?</h1>
                <a href="#" data-icon="refresh" ng-click="reload()">Reload</a>                
            </div> 
            
            <div data-role="content">
                
                <div class="content-primary">    
                    <p>{{ message }}</p>
                   
                    <div data-role="collapsible" 
                         ng-repeat="toilet in toilets | limitTo: itemsLimit()">
                        <h3>
                            {{ toilet.name }} 
                            ({{ toilet.lastCalculatedDistance() | distance }}) 
                            {{ toilet.isPaying | isPayingDollarSign }} 
                        </h3>                        
                        <p><strong>Name: </strong>{{ toilet.name }}</p>
                        <p><strong>Distance: </strong>{{ toilet.last..() | distance }}</p>
                        <p><strong>Paying: </strong>{{ toilet.isPaying | isPayingYesNo }}</p>
                        <p><strong>Street: </strong>{{ toilet.street }} </p>
                        <p><strong>Housenumber: </strong>{{ toilet.houseNumber }} </p>
                        <a href="{{ toilet.getMapUrl() }}" data-role="button">
                            Show location on a map
                        </a>
                    </div>                     
                             
                    <div ng-show="hasMoreItemsToShow()">
                        <button ng-click="showMoreItems()">Show more toilets</button>    
                    </div>        
                </div>        

            </div> 
            
            <div data-role="footer">
                <h4>Made possible by Antwerp Open Data</h4>
            </div> 
        </div>
    </body>    
</html>
You might notice how I used filters to format the isPaying and distance property. These are also defined in the module.
toiletApp.module.filter('isPayingDollarSign', function () {
    return function (value) {
        return value ? "$" : "";
    }
});

toiletApp.module.filter('isPayingYesNo', function () {
    return function (value) {
        return value ? "Yes" : "No";
    }
});

toiletApp.module.filter('distance', function () {
    return function (value) {
        return value ? value + "m" : "";
    }
});
You can find the working bits on AppHarbor. Source is on GitHub.

Summary

I can only applaud the Open Data initiative; my hope is that the datasets get more interesting though. Which also makes me wonder if the government is even measuring the more interesting stuff?

All in all, these two applications aren't very innovative. Yet, they did give me the opportunity to experiment with some stuff I can't play with on the day job (yet). I'm always amazed how quickly you can slap together a small application using the available building blocks out there. I'm most content with picking up angular.js; I will be advertising this framework in a professional context from now on.

Wednesday, December 12, 2012

Show More pagination with angular.js

I built my first application with angular.js over these last few weeks (not during business hours), and although I still have lots and lots to discover and learn, I think I somewhat grasp the basics.

In the application I built, I had to implement paging because rendering all the items at once was too slow on mobile devices (on my Windows Phone 7 anyways). The paging variant I decided on was the 'Show More' technique.

Let me walk you - as an introduction to Angular - through a simple application that uses paging for a list of 24 items.

We start by defining a module. In an Angular module, you should instantiate, wire and bootstrap parts of your application.
var module = angular.module('module', []);
We can already bind the module to our empty view.
<div ng-app="module">
</div>
In our module we want to define an itemService which will return an array of 24 items. By using a factory method we make our service an injectable dependency for other parts of our application.
module.factory('itemService', function() {
    return {
        getAll : function() {
            var items = [];
            for (var i = 1; i < 25; i++) {
                items.push('Item ' + i);                       
            }
            return items;
        }
    };              
});
Now that we have a service that can give us items, we want to work towards actually rendering these items. To do that, we'll have to define a controller. An Angular controller lets you augment an instance of Angular's scope, which in its turn serves as your connection to the view. 
ListController = function($scope, itemService) {
    $scope.items = itemService.getAll();    
};
Notice how we use dependency injection to inject an instance of the itemService.

All our items are available on the scope now, but we still have an empty view. Let's fix that.
<div ng-app="module" ng-controller="ListController">
    <ul>
       <li ng-repeat="item in items">
          {{ item }}        
       </li>               
    </ul>
    <button>Show more</button>    
</div>
Items are being rendered making use of Angular's built-in ng-repeat directive. Directives are - as the documentation puts it nicely - a way to teach HTML new tricks. MVC folks may think of it as HTML helpers.

What's left to do in this example, is what we initially set out to do; implement paging. For that, we'll first add some extra variables to the controller, and some new methods on to the scope. These should be self-descriptive.
ListController = function($scope, itemService) {
    var pagesShown = 1;
    var pageSize = 5;
    $scope.items = itemService.getAll();
    $scope.itemsLimit = function() {
        return pageSize * pagesShown;
    };
    $scope.hasMoreItemsToShow = function() {
        return pagesShown < ($scope.items.length / pageSize);
    };
    $scope.showMoreItems = function() {
        pagesShown = pagesShown + 1;         
    };
};​
We can now make use of those new methods on the scope in our view. 
<div ng-app="module" ng-controller="ListController">
    <ul>
       <li ng-repeat="item in items | limitTo: itemsLimit()">
          {{ item }}        
       </li>               
    </ul>
    <button ng-show="hasMoreItemsToShow()" ng-click="showMoreItems()">Show more</button>    
</div>
We made use of directives to add behaviour to the 'Show more' button and used the limitTo filter to limit the number of items rendered. Filters are used to format display data.

Here is the full jsFiddle.

I'm pretty sure you can abstract paging into a reusable component, but I thought this scenario shows a good bunch of basic Angular concepts.

So what are your thoughts on Angular? Pretty slick, right? Or are you already using Angular?

Sunday, December 9, 2012

It's not cake we are baking

I recently watched a talk on Vimeo where Christin Gorman talks about how cookie dough relates to Hibernate; why use the generic, bloated and one-fits-all solution when you can mix together your own yummy cookie dough? We should aspire to be the Gordon Ramsey of software, not the college student who can only cook Ramen noodles. If you haven't watched or listened to her talk, you should; it's only a few minutes long, and she brings it really well. Go ahead, I'll wait.

When I first watched her talk, it rubbed me the wrong way, but I couldn't yet figure out the flaw in her plea. It recently dawned upon me that we are not in the business of baking cakes, but we are in the business of serving hungry people. And those people really don't care which ingredients were used to bake your cake; they only care about how it tastes, how fast it's served, and how much they're paying for it. And although the romantic in me really sympathizes with her view, the realist just can't. Over these few years only, each and every attempt of a hand-rolled ORM I've seen, ended with a horrible aftertaste. There is no way that you spend as much time building a good API from scratch as you do setting up an existing one. Writing and maintaining your own ORM is not a trivial thing to do, and there are already so many flavors* - from grandma's recipe to decadent supreme deluxe - to pick from, that it's hardly ever a justified decision. Read the package and choose the option that satisfies your daily caloric needs, and go from there. You can still sweeten, or swap some ingredients, before serving. And if you really can't resist - which is perfectly healthy, bake all the cake you want, at home. Maybe, one day, you can bring a successful one to work.

* NHibernate, Entity Framework, Dapper, Massive, Simple.Data, LLBLGen Pro, OpenAccess, SubSonic ...

Sunday, December 2, 2012

Some notes on performance tuning with NHibernate

A few weeks back, I spent an intensive day performance tuning parts of a, to me, relatively unfamiliar part of our codebase. Like it often is, the biggest optimizations were to be found in how we work with the database. Now, I don't consider myself to be an NHibernate expert; I read this book and have used it on two projects, but in the end I just do my best to avoid doing stupid things with it. The topics discussed below are mostly common knowledge for long time NHibernate users, but I thought it might be convenient for others to just summarize them, and add references to other, more in-detail, posts.

Under the covers

When you're looking into optimizing, you probably want to have a look at what's really going on. You could do this by turning on NHibernate's log4net debug logging. This might be good enough for some scenarios, but it's not really convenient for when there is lots and lots of stuff happening. Instead, you might want to look into NHibernate Profiler. It's trivial to get started with, yet the feedback it provides is very powerful: next to session statistics and executed queries, you also get alerts which suggest techniques to improve your code. I need to use this tool more often just to get a better grip of the NHibernate internals.

The fastest query is the one that isn't

Going to the database is probably one of the slowest things your application is going to do. If you can avoid it, do so.

If you're using a stateful session, NHibernate will track your entities, and store them in its first level cache. When you get these items by id later on, you avoid going to the database. So instead of querying the database for the same entity multiple times in the same session, do it once, and get the entity by its id on subsequent calls.

When you're having a hard time keeping those ids around, consider introducing a light-weight datastructure, such as a dictionary, which can help you build a small look-up cache. This could also be a sign that you might want to reconsider your identity strategy though.

Working with batches

An ORM really isn't the best tool to do bulk inserts or updates; look at SqlBulkCopy instead.

If your batches are still relatively small, and you opt to stay with NHibernate anyways, there are two things you can do which will improve performance tremendously: use a stateless session and configure batching.

Switching to a stateless session is simple enough. Do take into account that some features won't work anymore: lazy loading, caching, cascading and implicit updates. Setting up batching is also just a matter of configuration. The most important thing to remember is to use an appropriate identity generator; batching will only work when the application is responsible for generating the ids. I'm using a HiLo generator, but GUIDs or assigned ids will work too. 

Sunday, November 25, 2012

Released: Kill long meetings

A lot has already been said and written about meetings, and some have carried the message above par; 'Meetings: where work goes to die'. Today, I'm not going to foul the internet with another rant, but I'd like to show you a small application built over the last few weeks after work.

I regularly find myself building small things as an antitoxin to the regular periods of not writing and shipping code at work. This time, me and @cgeers, built a not-so-serious application that aims to kill long meetings by visualizing the amount of time and money burned in a meeting.

While the application in itself probably will never attract a sustainable user base, development sprouted two useful Twitter Bootstrap plug-ins: a spin edit control and a multi-color progressbar.

Used technology stack 

On the server, we're using Nancy on an ASP.NET host with Razor views. There is hardly anything going on at the server, so we could have picked any server-side framework I guess. We might just be attracted to the as 'little friction as possible' Nancy ethos though. Returning a view, and setting up a route for it, takes just a few LOC.
namespace KillLongMeetings
{
    public class RootModule : NancyModule
    {
        public RootModule()
        {
            Get["/"] = p => View["HomeView"];
        }
    }
}
Next to returning a correct view, we're also making bundles on the server. For that, we're using Cassette for Nancy.

At the client, we chose to use Twitter Bootstrap, because getting a lay-out right that works everywhere these days is hard; we like to spend that time on other things. Next to jQuery - duh, we're using knockout.js as our client-side MVVM framework. This worked out lovely for our scenario, but overall, I'm distancing myself a bit from this framework. It's simple, and extremely easy to get started with, but lots of companies I heard of seem to adapt this as an application framework, which it is not. It's just two-way model binding in the browser. More complex scenarios benefit from a cleaner separation of concerns for validation, working with remote data, application composition and testing. Right now, I'm doing something with angular.js, and it seems very promising so far. It's also a lot less intrusive than knockout.js.

We're using AppHarbor and GitHub for continuous deployment. The production site however is a static site hosted on GitHub pages. Next to serving everything really fast, we're now not paying for anything except the domain name.

You can give it a quick spin at killlongmeetings.com. The source can be found on GitHub. Let us know what you think!

Sunday, November 18, 2012

Released: Nancy.AspNetSprites.Razor

I was setting up a web application that shows an image for each listed product on the home page. When there were a few products, this worked pretty smooth, but as the number of products (and thereby images) increased, performance degraded. The problem is that each image initiates a separate request. The solution for this problem is to reduce the number of requests by combining the images using CSS sprites. Here is an in-detail explanation of how this works.

I remembered the Hanselman writing about a Nuget package which does all the heavy lifting for you: Microsoft's ASP.NET Sprite and Image Optimization.
The ASP.NET Sprite and Image Optimization framework is designed to decrease the amount of time required to request and display a page from a web server by performing a variety of optimizations on the page’s images. This is the fourth preview of the feature and works with ASP.NET Web Forms 4, ASP.NET MVC 3, and ASP.NET Web Pages (Razor) projects.
Installing that package, it dawned on me that I wasn't using Mvc, nor WebForms, but Nancy on an ASP.NET host with the Razor view engine. So out-of-the-box, this package couldn't work for me.

I looked at the project a bit, and discovered that it would be easily portable to Nancy (on an ASP.NET host with the Razor view engine). It consists of three parts: AspNetSprites-Core, AspNetSprites-WebFormsControl and AspNetSprites-MvcAndRazorHelper. I could make use of the core package, and port the Mvc package to Nancy. The port was pretty straightforward; I removed the Mvc dependencies, and returned Nancy's IHtmlString instead of Mvc's IHtmlString. Note that this all still heavily relies on ASP.NET and its infrastructure.

I packaged this project for Nuget yesterday, and the source is on GitHub (under the MIT license).

Here is some documentation shaped as a how to.

Create an Empty ASP.NET Web Application

You can use the ASP.NET Empty Web Application template.

Install the package
PM; Install-Package Nancy.AspNetSprites.Razor
Attempting to resolve dependency 'AspNetSprites-Core (= 0.4)'.
Attempting to resolve dependency 'Nancy (= 0.13.0)'.
Attempting to resolve dependency 'Nancy.Hosting.Aspnet (= 0.13.0)'.
Attempting to resolve dependency 'Nancy.Viewengines.Razor (= 0.13.0)'.
Successfully installed 'AspNetSprites-Core 0.4'.
Successfully installed 'Nancy 0.13.0'.
Successfully installed 'Nancy.Hosting.Aspnet 0.13.0'.
Successfully installed 'Nancy.Viewengines.Razor 0.13.0'.
Successfully installed 'Nancy.AspNetSprites.Razor 0.0.2'.
Successfully added 'AspNetSprites-Core 0.4' to SpritesExample.
Successfully added 'Nancy 0.13.0' to SpritesExample.
Successfully added 'Nancy.Hosting.Aspnet 0.13.0' to SpritesExample.
Successfully added 'Nancy.Viewengines.Razor 0.13.0' to SpritesExample.
Successfully added 'Nancy.AspNetSprites.Razor 0.0.2' to SpritesExample.
This will add the references, alter the web.config, add an App_Sprites folder and add the necessary conventions automatically.

Known issue: depending on the name of your assembly, the AppSpritesConvention might be overwritten by one of Nancy's conventions. While I'm trying to come up with a good solution, you can move the convention to your bootstrapper.

Add images to the App_Sprites folder

Add the images you want to make sprites for to the App_Sprites folder. You can also make use of subfolders. In this example I added two images: image1.jpg and image2.jpg.

A working example

Add a simple Nancy module which returns a view named View.
public class Module : NancyModule
{
    public Module() 
    {
        Get["/"] = p => View["View"];
    }
}
In your view, make use of the Sprite.ImportStyleSheet and the Sprite.Image method to include the stylesheet and images.
<!doctype html>
<html>
    <head>   
        @Sprite.ImportStylesheet("~/App_Sprites")
    </head>
    <body>
    @Sprite.Image("~/App_Sprites/image1.jpg", new Dictionary<string, object>()
    {
        { "alt", "First image" }, 
        { "title","First image" }
    } )

    @Sprite.Image("~/App_Sprites/image2.jpg", new Dictionary<string, object>()
    {
        { "alt", "Second image" }, 
        { "title","Second image" }
    } )
</body>
The outputted HTML and CSS now looks like this.
<!doctype html>
<html>
<head>   
    <link href="App_Sprites/highCompat.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
    <img alt="First image" class="image1.jpg" src="data:image/gif;base64,..." title="First image" />
    <img alt="Second image" class="image2.jpg" src="data:image/gif;base64,..." title="Second image" />
</body>

.image1\.jpg
{
    width:468px;
    height:315px;
    background-image:url(sprite0.png);
    background-position:0px 0px;
}
.image2\.jpg
{
    width:468px;
    height:315px;
    background-image:url(sprite0.png);
    background-position:-469px 0px;
}

I hope it will prove useful for someone in the future. Let me know if you have any feedback or questions.

Wednesday, November 14, 2012

No trains today? No resources were found either.

Belgian's National Railway has decided to strike again today to assail Europe's oncoming austerity. I don't think there is anything wrong with sticking it to the man, or fighting for your right to party, if you believe it is just, yet the preferred tactics don't feel quite right. There must be more constructive ways to get your point across, instead of terribly inconveniencing all those people who give you a job in the first place, your customers. Any takers on proposing better alternatives?

With an average of 7 days of striking per year, it's self-evident that bashing our railway company has become a national sport. I hardly ever participate, but today I'm happy to make an exception. I have something tangible to show; a mini The Daily WTF. This weekend my girlfriend called me over to her desk to show me this.


Taking it out on their IT department might not be completely fair, but I couldn't resist. How do you succeed in putting your home page in production like that? It wasn't even fixed for quite some time. You can see by looking at the url and the source that they're using ASP.NET WebForms, but they must be rolling their own technique for localization. I can't imagine this passing through  acceptance without someone noticing, so it has to be a deployment issue. Was the production build only partially successful? Did those unfortunate few having to come in on weekends for deployment forget to carry out a manual procedure? Did someone bork the production configuration? Why did it take so long to rectify this? Was the gap between the teams responsible for development and deployment too wide? Was there no monitoring for these 'NOT_FOUND' errors? Are they even being treated as such? Did anyone even bother to smoke test after deployment?

Is there anyone else who wants to take a stab at guessing what went wrong here? 

Sunday, November 11, 2012

jQuery-validate error messages in Twitter bootstrap tooltips

At work, we're using the combination of ASP.NET MVC3, jQuery, jQuery-validate, knockout and Twitter Bootstrap on one of our projects. Having postponed looking at the aesthetics of the client-side validation for too long, we eventually found ourselves unsatisfied with the default error labels. Wanting to save on space, we're experimenting with the error messages being shown in a Twitter Bootstrap tooltip. After poking around for some while, I came up with something satisfactory.

In this example, I have a bootstrapped form that looks like this.
@using (Html.BeginForm("ChangePassword", "Account", FormMethod.Post, new { @class = "form-horizontal"})) {
    <div class="control-group">
        <label class="control-label">Old password</label>
        <div class="controls">
            @Html.PasswordFor(m => m.OldPassword)                            
        </div>       
    </div>
    <div class="control-group">
        <label class="control-label">New password</label>
        <div class="controls">
            @Html.PasswordFor(m => m.NewPassword)                
        </div>
    </div>
    <div class="control-group">
        <label class="control-label">Confirm password</label>
        <div class="controls">
            @Html.PasswordFor(m => m.ConfirmPassword)                
        </div>                            
    </div>  
    <div class="control-group">
        <div class="controls">
            <button type="submit" class="btn btn-primary">Change password</button>
        </div>
    </div>
}
To make the error messages show up in tooltips on the input controls, I eventually ended up with the snippet below.
$.validator.setDefaults({
    showErrors: function (errorMap, errorList) {
        this.defaultShowErrors();                            

        // destroy tooltips on valid elements                              
        $("." + this.settings.validClass)                    
            .tooltip("destroy");            

        // add/update tooltips 
        for (var i = 0; i < errorList.length; i++) {
            var error = errorList[i];
                         
            $("#" + error.element.id)
                .tooltip({ trigger: "focus" })
                .attr("data-original-title", error.message)                
        }
    }
});
I'm setting a custom showErrors function to extend the behaviour of the jQuery validator. I don't want to lose the default behaviour (highlighting etc), so I start with invoking the default showErrors function, to then destroy the tooltip on all valid input elements and to finally add or update the tooltip and its title on all invalid input elements. The errorList argument holds all the information I need for this; an array of invalid elements and their corresponding error messages.
[Object, Object]
> 0: Object
>> element: <input>
>> message: "The Current password field is required."
> 1: Object
>> element: <input>
>> message: "The New password field is required."
> length: 2
The end result looks like this.


Sunday, November 4, 2012

Commuting? Have you done the math?

On my first job interview, over four years ago, I was asked whether I would relocate if I was hired. Back then, I still lived in the Campine region with my parents, while the Ferranti Computer Systems headquarters are in Antwerp. I thought about it for a few seconds and told the interviewer that I didn't plan on moving out of my parents' place in the first few years. Besides, the distance isn't that great; it's only 60km (=37 miles) of highway, how bad could it be? Apparently that reply was good enough since I was given the job a few days later.
Well, that commute grew old rather quickly though. Turns out that those 60km of highway are one of the most saturated pieces of asphalt in Belgium, with up to 20 to 30km (12 to 18 miles) of systematic traffic jams every damn single day.

And when you have to take the car to work, the options you have to spend that time useful are rather limited; the only things I could think of at the time were listening to podcasts and reflecting on the things of life. The latter made me hate my situation even more, so that wasn't an optimal pastime.

I actually never had the courage to calculate how much time I wasted in traffic those three years. Today, I'm in a far more comfortable situation, so plucking up courage wasn't that hard anymore. With 52 weeks in one year, and 5 days in a week, there are 260 business days in one year. In Belgium, we don't work on all of those though, so I had to subtract 25 vacation days, and 6 holidays; bringing down the number of working days to 229. My rather optimistic guess is that I was on the road for somewhere around 140 minutes each day. So 229 days multiplied by 140 minutes comes down to a total of 32060 minutes, or 534 hours, or 66 working days. Gasp! 66 working days per year gone to waste. I knew the numbers were going to be bad, but this is even a lot worse than I expected.

Easing this burden isn't trivial though, and I can only think of a few feasible options, excluded changing jobs:
  • Travel outside rush hours: leave for work very early or really late. I experimented with the former for quite some time, but I never really got used to it. It also seems a bit counterproductive to have your rhythm be too different from that of your team members. I'm guessing your family life will suffer as well, but I can't be the judge of that.
  • Bring the office to you. In this technological day and age there are hardly any sound arguments not to encourage working from home. Yet, the classical enterprise shies away from embracing it and seems to be more comfortable sticking with the status quo than improving working conditions for their employees. 
  • Relocate. This option might be drastic, yet it's the one with the biggest probability of success.
  • If possible, use public transport. Even if your total time enroute increases, you will have more time to do something productive while you take away some of the frustration that comes along with commuting by car.

Earlier this year, I moved from one of the (work-wise) more remote corners of Belgium to a far better located area; the heart of Antwerp. To top that, I'm now living and working within walking distance of the train station, so I'm taking the train on a daily basis. In total I'm still on the go more than two hours, but I can now spend 75% of that time usefully. That's 43 working days extra to spend each year! I've made a habit out of using that commute time for self-study; reading, working on side projects and writing. This seems to have considerably affected my state of mind for the better. I get home at night, and I've already spent a considerable amount of time challenging myself intellectually. I now no longer stress about practicing less 'productive', but very enjoyable activities; such as playing the guitar, working out or doing stuff around the house. I get to have both now.

There are only so few hours in a day, having to spend a considerable amount of that time just to get somewhere seems such a waste. Every day we try tools and techniques which save us a few minutes, and should help us improve the quality of our day-to-day lives, yet we often disregard optimization of the biggest time hog of them all. It goes without saying that those numbing long commutes by car aren't something that I'll ever decide to go back to lightly.

When I read my Twitter feed in the morning, I see a lot of other Belgian people complain about their commute. Is this a Belgian thing only? Which means of transport do you use for the commute? How long are you on the road each day? Have you done the math? 

More comments on Hacker News.

Thursday, November 1, 2012

NancyFx and bundling with Cassette

Working on a new side project built using NancyFx, I wanted to bundle and minify my css and script resources. Looking into the options, Cassette (*) seemed the most obvious option.

Since I struggled with the implementation a little bit, I documented the process below.

1. Cassette.Nancy package

Add the Cassette.Nancy package to the project.
PM> Install-Package Cassette.Nancy
Attempting to resolve dependency 'Cassette'.
Attempting to resolve dependency 'AjaxMin (= 4.60)'.
Attempting to resolve dependency 'Nancy'.
Attempting to resolve dependency 'Nancy.ViewEngines.Razor'.
Attempting to resolve dependency 'NLog'.
Successfully installed 'AjaxMin 4.60.4609.17023'.
Successfully installed 'Cassette 2.0.0'.
Successfully installed 'NLog 2.0.0.2000'.
Successfully installed 'Cassette.Nancy 2.0.0'.
Successfully added 'AjaxMin 4.60.4609.17023' to Project.
Successfully added 'Cassette 2.0.0' to Project.
Successfully added 'NLog 2.0.0.2000' to Project.
Successfully added 'Cassette.Nancy 2.0.0' to Project.
2. Bundle configuration

The Nuget package adds the CassetteBundleConfiguration class to the root of your project.

I'm lucky to have my assets structured rather simply, which makes setting up the bundles take little to no effort.

public class CassetteBundleConfiguration : IConfiguration<BundleCollection>
{
    public void Configure(BundleCollection bundles)
    {
        bundles.AddPerSubDirectory<StylesheetBundle>("Content");
        bundles.AddPerSubDirectory<ScriptBundle>("Content");
    }
}
Each sub-directory now becomes a bundle.

To arrange the files in the bundles, I added a bundle.txt file that defines the order to each sub-directory. For the css sub-directory it looks like this.
bootstrap.css
bootstrap-responsive.css
docs.css
3. Using bundles

To use these bundles in my view, I first reference them, for then to render them in their optimal location - css in the head section, and scripts just before the closing body tag.
@using Cassette.Nancy

@{
    Bundles.Reference("Content/css");
    Bundles.Reference("Content/scripts");
}

@Bundles.RenderStylesheets()
@Bundles.RenderScripts()
4. First try

When you now browse to your application, and view the source, you'll notice that Cassette is already in play, yet the assets are not bundled nor minified.



5. Enable optimization

Apparently when using NancyFx, you need to explicitly enable optimization.
By default, the output from Cassette is not optimized. When output is optimized, Cassette modules are combined (bundled) based on the configuration and sent to the client as a single lump per bundle instead of lots of individual files.
When you're using ASP.NET MVC, this is dependant on the compilation debug switch.

The best place to enable this, is probably in your bootstrapper.
public class Bootstrapper : DefaultNancyBootstrapper
{
    public Bootstrapper()
    {
        Cassette.Nancy.CassetteNancyStartup.OptimizeOutput = true;
    }
}
6. Second try

This time around, the assets do get bundled and minified.



* It wasn't until today that I noticed the asset in Cassette. 

Monday, October 22, 2012

Post Web.NET Europe

I attended and spoke at Web.NET Europe in Milan over the weekend. This was only my fourth full day- or more conference (Techdays Belgium, TechEd Berlin and HTML5 WebCamps), but it was undoubtedly the best one so far.

The quality of the sessions was definitely not inferior to those of bigger conferences. I especially enjoyed the talks on SignalR, OAuth and scaling data (I included some of my notes below). The strength of this conference doesn't lie in the exceptional speakers or sessions though, but in its cozy size and the type of attendees it attracts. Being hosted on a Saturday, you already preclude all the developers who merely think of technology as a job. And when you put together those who care about what they do, and want to get better at it, good things happen. This was the first conference where I was able to talk to such a wide range of people - I guess I even spoke to more than six different nationalities - and where it didn't feel awkward one bit. What helps in attracting such a variety of people, is that the conference is practically free and survives on donations from sponsors and attendees, making it very affordable even if you fly in from outside of Italy. Freelancers also seemed to appreciate that it was on a non-billable day.

In short, I really enjoyed the experience, and it might be just so that weekend conferences make for better conferences. Congratulazioni a Simone Chiaretta and Ugo Lattanzi for making this happen. I'm already looking forward to the next edition.




"Real Time" Web Applications with SignalR in ASP.NET (@A_Giorgetti)

Last year I did a talk on WebSockets at HTML5 WebCamps and although I built a few things that worked, the real-time web in the wild was still very much a mess. SignalR now abstracts all that clutter for you, and provides you with a seemingly clean infrastructure and simple API. Too bad the use for real-time web applications is rather limited in my world - stock ticker or chat application anyone?

OAuth-as-a-service using ASP.NET Web API and Windows Azure Access Control (@maartenballiauw)

I had my first serious look at OAuth in this session, and while it's probably indispensable for public API's, it doesn't seem that trivial to implement. Azure ACS could make this easier though.

Slides

Scaling without going crazy (@Ayende)

This was one of the talks I really looked forward to, and it didn't disappoint one bit. I never got to do anything with big data (data that can't fit on one machine), but there are really interesting problems and trade-offs in that space - CAP theorem etc.

Some quotes worth giving more thought:
  • Caching often just hides a problem.
  • How is Facebook consistent? It's personally consistent.

Sunday, October 21, 2012

Slides and code from my Web.NET Europe REST and ASP.NET Web API session

I just returned to the hotel after attending and speaking at Web.NET Europe 2012. There were multiple sessions on ASP.NET Web API today, and I was responsible for delivering the first one of the day. Being first, and to avoid overlap with others, I tried to lay a solid foundation by focusing on the REST and ASP.NET Web API basics: resources, identifiers, representations, verbs and hypermedia.

More people than I expected showed up for my talk; somewhere around 50 to 70 attendees, I guess. I think it was fairly well received; after 25 votes, the session rating stands at 90%. It's great to see your preparations have such a fruitful outcome.

I still have a few thoughts on the conference to materialize, but for now, I uploaded the slides (they're also embedded below) and hosted the source code on GitHub.


Monday, October 15, 2012

Commands with dependencies

Also read: Separating command data from logic and sending it on a bus

Yesterday I wrote about an architecture which limits abstractions by solely introducing commands and queries. I shared a dead simple variation of this pattern, the advantages I experienced, and how I could still unit test the controller if I wanted to.
At the end of that post I wondered how I would be able to test commands in isolation; suppose the implementation doesn't use a database this time, but a hairy, too low-level, third party webservice.

Right now, the input arguments are inserted via the constructor, but this leaves no room to inject dependencies. That is, if we don't want to do awkward stuff with our Dependency Injection framework, and don't want to resort to property- or method injection.
public class WithdrawAmountCommand : Command
{
    public WithdrawAmountCommand(string user, int amount)
    {
        if (string.IsNullOrEmpty(user))
            throw new NullReferenceException("user");

        User = user;
        Amount = amount;
    }

    public string User { get; private set; }

    public int Amount { get; private set; }

    public override void Execute()
    {
        // Implementation
    }
}
One way to enable injecting dependencies could be to separate the command in two parts; the handler, and the data.
public interface ICommandHandler<in TCommandData> 
{
    void Execute(TCommandData commandData);
}
Now we could rewrite the WithdrawAmountCommand. One class contains and verifies the input data...
public class WithdrawAmountCommandData
{
    public WithdrawAmountCommandData(string username, int amount)
    {
        if (string.IsNullOrEmpty(username))
            throw new NullReferenceException("username");

        Username = username;
        Amount = amount;
    }

    public string Username { get; private set; }

    public int Amount { get; private set; }
}
...while the second class actually acts on the data.
public class WithdrawAmountCommandHandler : ICommandHandler<WithdrawAmountCommandData>
{
    private readonly IAccountWebservice _accountWebservice;

    public WithdrawAmountCommandHandler(
        IAccountWebservice accountWebservice)
    {
        _accountWebservice = accountWebservice;
    }

    public void Execute(WithdrawAmountCommandData data)
    {
        _accountWebservice.Invoke(data.Username, data.Amount);
    }
}
Testing commands in isolation is now straight-forward.
[TestMethod()]
public void Execute_should_invoke_webservice_with_correct_arguments()
{
    var accountWebService = new Mock<IAccountWebservice>();

    var command = new WithdrawAmountCommandHandler(accountWebService.Object); 
    command.Execute(new WithdrawAmountCommandData("JefClaes", 25));

    accountWebService.Verify(aws => aws.Invoke("JefClaes", 25));
}
Don't forget that the controller also needs to accommodate this change.
public class HomeController : Controller
{
    private readonly IQueryHandler _qryHandler;
    private readonly ICommandHandler<WithdrawAmountCommandData> _withdrawAmountCommandHandler; 

    public HomeController()
    {
        _qryHandler = new QueryHandler();
        _withdrawAmountCommandHandler = new WithdrawAmountCommandHandler(new AccountWebservice());
    }

    public HomeController(
        IQueryHandler qryHandler,
        ICommandHandler<WithdrawAmountCommandData> withdrawAmountCommandHandler)
    {
        _qryHandler = qryHandler;
        _withdrawAmountCommandHandler = withdrawAmountCommandHandler;
    }

    [HttpPost]
    public ActionResult Foo(string user)
    {
        _withdrawAmountCommandHandler.Execute(new WithdrawAmountCommandData(user, 25));

        var totalAmount = _qryHandler.Execute<int>(new TotalAmountQuery(user));

        if (totalAmount < 0)
            return RedirectToAction("Warning");

        return RedirectToAction("Index");
    }
}
I'm not all that happy with how this approach will bloat my controller in the future to be honest. To smooth out this friction, I could - like in the previous post - introduce a dispatcher, which serves as an intermediary for the commandhandlers.

Integration testing wasn't an option in this scenario, so I had to introduce some extra abstractions just to facilitate unit testing. Although this particular variation still holds lots of advantages I talked about in my previous post, there's already a lot more boilerplate and some more complexity.

I'm going to give this topic some more thought. Care to share yours?