Mikael's blog

A developers seventh time trying to maintain a blog

Cleaning up

I’m starting to have quite a few views in CouchDB and I’ve done my best to name them in a logical way so that I can easily see what they do by reading their names. Today I created a couple of new views and I decided that I needed to rename some old ones for clarity. Just when I was about to hit ‘Save’ on one of my design documents I felt a cold shiver going down my spine. I stopped and thought about it for a second and I realized that I don’t have a separate database for my development environment, nor do I want to have one.

This made me take a different strategy. At the moment I have a lot of views that does the same thing but are named differently. That’s because I created new views, with better names, instead of removing the old ones. I will remove the old ones after I’m done making sure that the development environment only uses the new views. That way I (hopefully) won’t break my production environment all of a sudden.

by Mikael Lofjärd

A Simple Routing Solution with Node.js

A few days ago I wrote about not reinventing the wheel. Today I’m going to talk about the opposite.

If you’re building an ‘enterprise’ grade application, reinventing the wheel is almost always the wrong thing to do. This blog however is something I do just for fun, and reinventing the wheel can sometimes be the best way to learn how stuff works. It’s one of the reasons Ayende had for writing yet another document database, and it’s the reason why I decided to write my own routing engine.

Sure enough I could have used the very popular Express framework, but where’s the fun in that?

What I wanted

As you might know, I work almost exclusively with the .Net stack at my job and I really like how routing is handled in ASP.Net MVC.

routes.MapRoute(
  "Default",	// Route name
  "{controller}/{action}/{id}",	// URL with parameters
  new { controller = "Home", action = "Index", id = "" }	// Parameter defaults
);

I wanted something similar in my blog; easy to read, easy to configure and abstracted away from all that goes on when the http request happens.

What I ended up with

This is my routing configuration (from index.js):

var routes = {};
// blog routes
routes['blog:/'] = masterController.page;
routes['blog:/post/{id}'] = masterController.getPost;
routes['blog:/comment'] = masterController.comment;
routes['blog:/page'] = masterController.page;
routes['blog:/page/{key}'] = masterController.page;
routes['blog:/archive'] = masterController.archive;
routes['blog:/admin'] = masterController.admin;
routes['blog:/admin/get/{id}'] = masterController.getPostAsJSON;
routes['blog:/admin/submit'] = masterController.submitPost;

// default static file route
routes['file'] = masterController.file;

I don’t have any complicated routes but never the less I wanted to have nice URLs. It also has support for virtual hosts which means I can have equal routes do different things depending on what sub domain I’m on.

If your’e wondering what the masterController is, it’s just a wrapper controller thats responsible for initializing all my other controllers so I can keep index.js a little less cluttered.

My virtual host configuration (from index.js):

var virtualDomains = {};
virtualDomains['lofjard.se'] =               { routeId: 'blog', wwwRoot: './content/lofjard' };
virtualDomains['www.lofjard.se'] =           { routeId: 'blog', wwwRoot: './content/lofjard' };
virtualDomains['xn--lofjrd-eua.se'] =        { routeId: 'blog', wwwRoot: './content/lofjard' };
virtualDomains['www.xn--lofjrd-eua.se'] =    { routeId: 'blog', wwwRoot: './content/lofjard' };
virtualDomains['foto.lofjard.se'] =          { routeId: 'foto', wwwRoot: './content/foto' };
virtualDomains['foto.xn--lofjrd-eua.se'] =   { routeId: 'foto', wwwRoot: './content/foto' };

I needed this since I have a photo site on a different sub domain that gets handled by the same node server.

And this is the router code:

/*****************************************
 *   Router
 *****************************************
 *   Author:  mikael.lofjard@gmail.com
 *   Website: http://lofjard.se
 *   License: MIT License
 ****************************************/

var Router = (function() {
  var url = require('url');
  var path = require('path');
  var querystring = require('querystring');

  var env = require('./environmentManager').EnvironmentManager;

  var resolveExcludes = ['.html', '.js', '.css', '.png', '.jpg', '.gif', '.ico', '.txt'];
  var virtualDomains = {};
  var routeTable = {};

  function buildRouteTable(routes) {
    for (var route in routes) {
      console.log('Server: Building route table entry for: ' + route);
      var routeSplit = route.split(':');
      var routeId = routeSplit[0]
      var routeName = routeSplit[1];

      if (routeName == null) routeName = route;

      var handle = routes[route];
      var pathName = routeName.split('/{')[0];
      var regexRoute = new RegExp(routeName.replace(/{\w+}/g, '{(\\w+)}') + '$', '');
      var regexPath = new RegExp(routeName.replace(/{\w+}/g, '([^\/]+)') + '$', '');
      routeTable[route] = {
        routeId : routeId,
        handle : handle,
        pathName : pathName,
        regexRoute : regexRoute,
        regexPath : regexPath
      }
    }
    return;
  }

  return {

    init: function(virtualDomainsInit, routes) {
      virtualDomains = virtualDomainsInit;
      buildRouteTable(routes);
    },

    route: function(request, response) {
      var pathName = url.parse(request.url).pathname;
      var hostName = request.headers['host'].split(':')[0];

      // if request is for unknown sub domain, let the file handler handle it
      if (typeof(virtualDomains[hostName]) === 'undefined') {
        routeTable['file'].handle(request, response);
        return;
      }

      if (resolveExcludes.indexOf(path.extname(pathName)) === -1) {
        env.info('Router: About to route a request for ' + pathName);

        for(var route in routeTable) {
          if (virtualDomains[hostName].routeId === routeTable[route].routeId &&
              routeTable[route].regexPath.test(pathName)) {
            var attributes = routeTable[route].regexRoute.exec(route);
            var values = routeTable[route].regexPath.exec(pathName);

            var qs = {};

            if (attributes.length > 1) {
              for (var i = 1; i < attributes.length; i++){
                qs[attributes[i]] = values[i];
              }

              request.url = routeTable[route].pathName + '?' + querystring.stringify(qs);

              env.info("Router: Rewrote request url as " + request.url);
            }

            routeTable[route].handle(request, response);
            return;
          }
        }
      }

      env.info('Router: Static file request for ' + pathName);
      
      // default fallback on static file handler if no route matched the request
      routeTable['file'].handle(request, response);
    }
  };
	
}());

typeof(exports) != 'undefined' ? exports.Router = Router : null;

Upon initialization it traverses all routes in the configuration and creates two regular expressions for each route. One RegEx is used for getting the attribute names and the other is used for fetching the attribute values.

When the request comes in I get the host name for the request and check if it exists in my virtual domain list. If it doesn’t I just hand things over to the static file handler which will serve up a 404.

I then check if the URL that was requested has a file ending that I know is a static file. If so I skip the routing code and my fallback static file handler takes care of the request.

If it’s not a known static file extension, then the fun begins. I traverse all the routes checking if it matches the RegEx for getting attributes and if the route id matches the one set up for the current virtual domain.
If it matches I extract the attributes and values, if any, and attach them to the request object as a querystring. I might rewrite this part in the future so that I just extend them as properties to the request object instead of using the querystring.

Then I execute the assigned function for that route. Done.

by Mikael Lofjärd

Hope

I was very happy when I saw this the other day.

I knew it was bound to happen, but for it to happen so soon was a nice surprise. Hopefully the ROM for the Galaxy Tab 8.9 won’t be far behind.

Samsung recently hired the founder of CyanogenMod, Steve Kondik, and since Samsung tends to take some time releasing their own ROMs, this seems like a nice way to speed things up at least for rooted Samsung device owners.

I’m really looking forward to using client certificates on my tablet.

Someone also managed to cram ICS onto his G1 today.

Now that’s impressive. This bodes well for my not-as-aging-as-a-G1 HTC Desire. It will be interesting to see if it can run Android 4.0 in any usable way.

by Mikael Lofjärd

Node.js Development Server Strategy

When I started building this blog my server was the production environment and my laptop was the development environment. This all changed when I added the database and started doing more UNIX specific stuff such as path resolving and such. So from then until yesterday my production environment was also my development environment. Not the best strategy I admit.

Yesterday when I rewrote the architecture I also decided that I needed to set up a separate node.js instance as a development environment on the server.

The first problem I had to solve was configuration. My configuration was scattered all over the code base so I moved it all into index.js which is the file I execute with node when I start the server.

I also did not want to have to change my configuration before I deploy (copy) from development to production, thus my code somehow needed to be aware of whether it was production code or development code.

Moving files around

Node.js has a global process object that holds information about the running node.js process. In the API for process is a method called cwd() that stands for Current Working Directory. It’s default value is the folder from where you called node.js when you started it.

Based on this I made my file structure as such:

  • /dev
  • /dev/content
  • /dev/controllers
  • /dev/views
  • /stable
  • /stable/content
  • /stable/controllers
  • /stable/views

There are a few other folders but these are the important ones.

The /dev and /stable folders are where my main code resides and where I execute node.js from. In the underlying /content folders, all of my CSS, images and client JavaScript resides.

In the last few years I’ve been doing a lot of ASP.Net MVC at work, and the MVC pattern was something that I felt really comfortable with, so I also created /controllers and /views folders. As all my data gets passed around as JSON, and JavaScript doesn’t have any classes, there are no Models to speak of so they didn’t get folders.

All in all, /stable is a mirror of /dev and I just copy all files from /dev to /stable when I feel that the code is stable.

Enter the EnvironmentManager

To make use of my new folder structure and process.cwd() I built the EnvironmentManager. Its sole purpose is to deal with environmental factors that differ from development and production.

It looks like this:

/*****************************************
 *   Environment Manager
 *****************************************
 *   Author:  mikael.lofjard@gmail.com
 *   Website: http://lofjard.se
 *   License: MIT License
 ****************************************/

var EnvironmentManager = (function() {

  var fs = require('fs');

  var misc = require('./misc').Misc;

  var currentEnvironment = null; // development or production
  var trackingCodeScript = null;

  return {

    init: function(trackingCodePath) {
      var cwdSplit = process.cwd().split('/');
      var cwdBase = cwdSplit[cwdSplit.length - 1];
      console.log('EnvironmentManager: Base dir is ' + cwdBase);

      if (cwdBase === 'dev') {
        currentEnvironment = 'development';
      } else {
        currentEnvironment = 'production';
        trackingCodeScript = fs.readFileSync(trackingCodePath);

        process.on('uncaughtException', function(err) {
          var log = fs.createWriteStream('exceptions.log', {'flags': 'a'});
          log.write(misc.getDateTimeNow() + ' - ' + err + '\n');
        });
      }
    },
		
    info: function(logMessage) {
      if (currentEnvironment === 'development') {
        console.log(logMessage);
      }

      return;
    },
		
    trackingCode: function() {
      if (currentEnvironment === 'production') {
        return trackingCodeScript;
      }
			
      return '';
    },
		
    httpPort: function() {
      return (currentEnvironment === 'development') ? 8080 : 80
    },
		
    httpsPort: function() {
      return (currentEnvironment === 'development') ? 8081 : 443
    }
  };

})();

typeof(exports) != 'undefined' ? exports.EnvironmentManager = EnvironmentManager : null;

It is initialized from index.js and checks if the current working directory is /dev. If it is, then we’re in the development environment, if not, we’re in production.

Here’s what it’s used for:

  • Upon initialization (in production) it adds a listener to the uncaughtException event on process so that instead of crashing (and getting restarted by supervisor) it logs the exception to disk.
  • It has a wrapper function around console.log(...) so that no logging to console is done in production.
  • If we are in production it can give me my Google Analytics tracking code that I give to the ViewManager to insert into views. That way I don’t polute my visitor statistics as I’m the only one using the development server.
  • It also gives me the port numbers to start the servers on depending on which environment we’re in.

The EnvironmentManager has been a nice addition to my code base as now I can deploy my development code to production without altering a single line of code. Hopefully this will lead to less downtime.

by Mikael Lofjärd

Architecture in Javascript - Modules

About a week ago I wrote about turning client side JavaScript into CommonJS modules. The scoping of variables in CommonJS makes this easy, but what if we wanted to do it the other way around?

In CommonJS, modules are scoped by file and all public methods and properties must be propagated through the exports object.

var foo = 'foo';

function bar() {
  return foo;
}

exports.bar = bar;

In the above example the foo property is private to the CommonJS module and can only be read from the outside by the public method bar().

If we were to include this JavaScript file on the client however, the property foo and the method bar() would both exist in the same scope as all other JavaScript files. What we need is to scope our module.

Object Literal Notation

In JavaScript, everything is an object. Object Literal Notation lets us take advantage of this and markup our module in a kind of ‘fake’ namespace.

var myModule = {
  foo: 'foo',

  bar: function() {
    return this.foo;
  }
};

exports.myModule = myModule;

Using Object Literal Notation we have now scoped our module inside a myModule namespace. If we were to include this JavaScript file on the client, only myModule would go into the global document scope.

The foo property is still public though and can be accessed using myModule.foo from the outside.

If you have no use for private properties then Object Literal Notation is an easy way to scope your module.

The Module Pattern

The Module Pattern (made popular by among others Douglas Crockford) is a clever mix of Immediately Invoked Function Expression and Object Literal Notation.
Instead of returning a function, as in IIFE, it returns an object.

var myModule = (function() {
  var foo = 'foo';

  return {
    bar: function() {
      return this.foo;
    }
  };
}());

exports.myModule = myModule;

Now the foo property is private to our module even on the client side. This is how I choose to build my modules yesterday when I rewrote the blog.

What about exports?

If you haven’t noticed by now, none of our examples actually works in the browser. That’s because the exports object doesn’t exist outside of the CommonJS world.

One could of course create it in the global document scope but a better way would be to include some sanity checks in our module.

typeof(exports) != 'undefined' ? exports.myModule = myModule : null;

Now we ignore exports if the object doesn’t exist.

Some blog source code

I’ve done this for everything in my source as it allowed be to break things up into smaller pieces, and I use a init(...) method in my modules return {...} statement to inject different dependencies from the outside.

Not all my modules make sense to put on the client of course, but one I made is actually usable on the client side as well.

/*****************************************
 *   Misc functions
 *****************************************
 *   Author:  mikael.lofjard@gmail.com
 *   Website: http://lofjard.se
 *   License: MIT License
 ****************************************/

var Misc = (function() {

  var dateTimeRegex = new RegExp('([0-9]+)-([0-9]+)-([0-9]+)T([0-9]+:[0-9]+).+&#36;', '');

  function doubleDigit(digit) {
    return (digit &lt; 10) ? '0' + digit : digit;
  }

  return {
    monthNames: ['unknown', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],

    dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],

    getDateTimeNow: function() {
      var now = new Date();
      var year = now.getFullYear();
      var month = doubleDigit(now.getMonth() + 1); //indexed from 0-11 =)
      var day = doubleDigit(now.getDate());
      var hours = doubleDigit(now.getHours());
      var mins = doubleDigit(now.getMinutes());
      var secs = doubleDigit(now.getSeconds());
      var tz = doubleDigit(-now.getTimezoneOffset() / 60); //offset in negative minutes

      return year + '-' + month + '-' + day + 'T' + hours + ':' + mins + ':' + secs + '+' + tz + ':00';
    },

    prettyDate: function(dateTime) {
      var parsedDateTime = dateTimeRegex.exec(dateTime);

      var year = parsedDateTime[1];
      var month = parseInt(parsedDateTime[2]);
      var day = parseInt(parsedDateTime[3]);
      var time = parsedDateTime[4];

      return this.monthNames[month] + ' ' + day + ', ' + year + ' at ' + time;
    }
  };

}());

typeof(exports) != 'undefined' ? exports.Misc = Misc : null;

I’m planning on making the entire blog source code available right here on the blog, but that will be the topic for another post.

by Mikael Lofjärd

Stupid admin

Sometimes I go to bed at night with an open ssh session running the server in the foreground. If that times out, so does the server. I really need to pay more attention to what I’m doing.

Sorry about the down-time… *ashamed*

by Mikael Lofjärd

Overhaulin'

Tomorrow (actually today when I write this) my daughters day care is closed and I get to spend the day with her at home. That meant that I could stay up late tonight and do some work on the blog.

The last few days I’ve felt that the file sizes were beginning to get out of hand. This easily happens when you’re writing JavaScript since it’s kind of a cowboy language. I love that I am able to twist and bend the language to my will, but the same thing that makes JavaScript so powerful can also be its worst enemy. It’s way to easy to loose control of yourself and before you know it you end up with a 1000-lines-of-code monster file and your head starts spinning every time you want to make a change to it.

So today I rewrote the blog. Not all of the logic, but basically all of the architectural stuff, and I’m quite pleased with the result. I’m going to write some more tomorrow (or later this afternoon, depending on your point of view) about what I’ve done and a bit on architectural patterns in JavaScript in general.

I was really excited about writing about it right now, but I need to get to bed now.

by Mikael Lofjärd

Why node-static is a good idea

If you are using node.js as a web server (as I am) and you want to serve up static files there are a lot of ways you can go about doing that. I’m going to talk about 3 of them.

The bad path: Serving them yourself

It’s really easy to do this for a proof of concept. Node.js has an easy to use fs library for reading and writing files to the file system. In order to serve up some HTML page you just parse the request URL, retrieve the file using fs.readFile(...) and then write the file to the response stream.

I did this for the small server I use at my Tuesday tutorials at work. The problem we faced last Tuesday was that our web site would not load properly in IE9 without resorting to “compatibility mode”.

At the time I didn’t have time to look into it (as I was tutoring) so I did it today instead, and I quickly figured out the problem. The same problem that would face anyone trying to write a web server in node using the fs library; MIME types.

There are a lot of MIME types involved when serving up a web page. HTML should be served as text/html and in our case encoded using UTF-8. CSS should be served as text/css and this turned out to be what broke our site in IE. And the images all have their own MIME type depending on whether they’re JPGs, PNGs or GIF’s etc, and they should be served as binary.

All in all, there’s a lot of stuff to keep track of and while you could do all of that in code, why reinvent the wheel?

Another issue with the fs approach is that you have to implement your own caching.

The good (or sometimes great) path: Using nginx

nginx is a small, fast, http proxy/static file server/cache/load balancer that does an awesome job serving up static files with correct MIME types and great caching. The only current issue with nginx is that it only supports HTTP 1.0 and thus is incompatible with web sockets.

If you know that you’re not going to use web sockets (or you’re going to do some nifty port redirection) then nginx is the way to go.

The best (for me) path: node-static

node-static is an awesome little node.js module and it’s sole purpose is to serve up static files. It takes care of caching, E-tags, MIME types and all that stuff and it’s really easy to use.

Some code from node-static’s github page:

var static = require('node-static');

//
// Create a node-static server instance to serve the './public' folder
//
var file = new(static.Server)('./public');

require('http').createServer(function (request, response) {
  request.addListener('end', function () {
    //
    // Serve files!
    //
    file.serve(request, response);
  });
}).listen(8080);

Since I haven’t decided on whether I want to use web sockets for anything on my blog yet, and I don’t really have any performance issues that requires me to look more into nginx, I went down the node-static path and hasn’t regretted it yet.

Now I just need to implement it into my Tuesday Web Track server. That will probably take me anywhere between 30 and 45 seconds. =)

by Mikael Lofjärd

Node TCP Client

A few weeks ago I bought an iTach IP2IR from a company called Global Caché. Combined with an iPhone app called iRule it lets me use my iPhone to control my home theater equipment.

This has been an awesome experience. No more fighting over remotes since my wife has the same app on her phone, and when our daughter wakes up on the weekends we can turn the TV on in the living room without leaving the bed and thus buy our selfs a couple of minutes more snooze time.

The thing that makes Global Caché more awesome than most hardware companies is that they publish their API specs on their web site, and it’s a really nice, simple ASCII based TCP API. The API is really what made me choose this product over similar options.

Since the API works over TCP I can connect with almost anything that has a network connection and an SDK. Today I chose to connect with node.js and create a little program that is both a TCP client and a WebSockets server. My client in this case was a simple HTML page with a button that sent a message over WebSockets, similar to what I did with SplitCode.

Here’s the whole source code:

var io = require("socket.io").listen(1338);
var net = require('net');

io.sockets.on('connection', function (client) {
  console.log('WS: client connected');

  client.on('togglePower', function(code) {
    console.log('WS: recieved togglePower command');

    togglePower();
  });
});

var tcpclient = net.connect(4998, '192.168.0.16', function() {
  console.log('TCP: client connected');
});

tcpclient.on('data', function(data) {
  console.log('TCP: recieved ' + data.toString());
});

tcpclient.on('end', function() {
  console.log('TCP: client disconnected');
});

function togglePower() {
  tcpclient.write('sendir,1:1,1,36023,1,1,325,161,21,61,21,61,21,61,21,61,21,20,21,20,21,20,21,20,21,20,21,60,21,61,21,20,21,20,21,20,21,20,21,60,21,20,21,60,21,20,21,20,21,60,21,20,21,20,21,20,21,60,21,20,21,60,21,61,21,20,21,60,21,61,21,61,21,1550,324,81,21,3602\r\n');
}

My iTach is on ip 192.168.0.16 and all communication is handled on port 4998.

I now have a button that can turn my IPTV STB on and off. It’s not much but it only took me all but 5 minutes to put together. =)

by Mikael Lofjärd

Programming Flu

This weekend I’ve been at home with some kind of wierd illness. At first I thought it was angina bacterial tonsillitis since that’s what my daughter came down with right before I left for Øredev. But now I’m thinking it’s something viral. Not in the Internet pretty-pictures-of-kittens way but an actual virus.

I’ve been having some fever but it hasn’t been that serious and my throat has been really soar, but it never really took of the way my daughters angina tonsillitis did.

However, I’ve been totally knocked down by it. I spend half the day in bed and the other half knocked out on the couch. So far it doesn’t sound all that different from my normal weekends but trust me, it’s different.

I’ve decided to name this illness “Programming flu”. What this programming flu does is take away all of your creativity. I’ve been staring at my blog this whole weekend without having the slightest idea of what to write about.

I usually have 5-6 things I wanna try out and at least one of them usually gets done and then written about. These are some of the things I planned to do this weekend:

  • Finish coding the administration interface for the blog
  • Try out some new layout stuff on the blog (maybe a side bar)
  • Get my new USB server hooked up with my Tellstick
  • Write some software to control my lighting and home theater equipment
  • Continue working on SplitCode for my next Tuesday tutorial at work

I’ve managed to get half way through the first one. In fact this is the first post written in the blog’s administration interface instead of in Couch’s.

But every time I’ve sat at the computer thinking of getting started on one of the other things and then blog about it, something keeps making me do something else. Programming flu is not fun.

I’m still not well so I’m calling in sick tomorrow. But my wife is going to work tomorrow and my daughter has day care so I’m hoping my programming flu will have eased off a bit tomorrow so I can finally get some work done. Hopefully there will be some code for you by tomorrow evening.

UPDATE: Some people pointed out the fact that angina probably wasn’t the transalation I was looking for and that what I really meant was tonsillitis. Never trust the first translation dictionary you find on the web.

by Mikael Lofjärd

Sorry, sharing is not available as a feature in your browser.

You can share the link to the page if you want!

URL