Monday, April 21, 2014

Solving Mavericks with VMware Fusion 6 and Windows 8.1 hangs

Since I intended to avoid Windows at home, I got a Macbook Pro starting out at my new job. Overall it has been a great machine for doing development; it's fast, light enough to carry around, its battery life is outstanding, it has a screen that's gentle to the eyes, and full screen apps together with powerful mouse gestures allow me to quickly shuffle between things not missing touch or a second monitor.

Most of my professinal work is still on the Microsoft stack though, so I'm running a Windows 8.1 VM on VMWare Fusion 6. Much to my frustration, this setup would gradually slow down my system until it would completely grind to a halt every few hours. After complaining about it on Twitter, people said that having 8GB of RAM with half of that allocated to the VM might not be enough.

However after applying some tweaks, I got my system to chug away for a week without any hangs.

Here is what I changed:
  1. Turn off App Nap for VMware
  2. Install Memory Clean
  3. Disable Windows visual effects (Advanced System Settings - Visual Effects)
  4. Turn off Resharper Solution-Wide Analysis
  5. Turn off Visual Studio rich client visual experience 
Hope it helps.

Sunday, April 6, 2014

Rebinding a knockout view model

As you might have noticed reading my last two posts, I have been doing a bit of front-end work using knockout.js. Here is something that had me scratching my head for a little while..

In one of our pages we're subscribing to a specific event. As soon as that event arrives, we need to reinitialize the model that is bound to our container element. Going through snippets earlier, I remembered seeing the cleanNode function being used a few times - which I thought would remove all knockout data and event handlers from an element. I used this function to clean the element the view model was bound to, for then to reapply the bindings to that same element.

This seemed to work fine, until I used a foreach binding. If you look at the snippet below, what is the result you would expect?
<div id="books">
    <ul data-bind="foreach: booksImReading">
        <li data-bind="text: name"></li>
    </ul>
</div>

var bookModel = {
    booksImReading: [
        { name: "Effective Akka" }, 
        { name: "Node.js the Right Way" }]
};
                         
ko.applyBindings(bookModel, el);

var bookModel2 = {
    booksImReading: [
        { name: "SQL Performance Explained" },
        { name: "Code Connected" }]
};

ko.cleanNode(books);
ko.applyBindings(bookModel2, books);
Two list-items? One for "SQL Performance Explained" and one for "Code Connected"? That's what I would expect too. The actual result shows two list-items for "SQL Performance Explained" and two for "Code Connected" - four in total. The cleanNode function is apparently not cleaning the foreach binding completely.

Looking for documentation on the cleanNode function, I couldn't find any. What I did find was a year old Stackoverflow answer advising against using this function - since it's intended for internal use only.

I ended up making the book model itself an observable. The element is now being bound to a parent model that contains my original book model as an observable. When the event arrives now, I create a new book model and set it to that observable property. This results in my list being rerendered with just two items - like expected.
<div id="books">
    <ul data-bind="foreach: bookModel().booksImReading">
        <li data-bind="text: name"></li>
    </ul>
</div>

var page = {
    bookModel : ko.observable({
        booksImReading: [
            { name: "Effective Akka" }, 
            { name: "Node.js the Right Way" }]
    })
};
                          
ko.applyBindings(page, el);

page.bookModel({
    booksImReading: [
        { name: "SQL Performance Explained" },
        { name: "Code Connected" }]
});
Don't use the cleanNode function to rebind a model - instead make the model an observable too.

Sunday, March 23, 2014

Sending commands from a knockout.js view model

While I got to use angular.js for a good while last year, I found myself returning to knockout.js for the current application I'm working on. Where angular.js is a heavy, intrusive, opinionated, but also very complete framework, knockout.js is a small and lightweight library giving you not much more than a dynamic model binder. So instead of blindly following the angular-way, I'll have to introduce my own set of abstractions and plumbing again; I assume that I'll end up with a lot less.

Let's say that I have a view model for making a deposit.
var DepositViewModel = function() {
    var self = this;

    self.account = ko.observable('');
    self.amount = ko.observable(0);

    self.depositEnabled = ko.computed(function() {
        return self.account() !== '' && self.amount() > 0;
    });
    
    self.deposit = function() {
        if (!self.depositEnabled()) {
            throw new Error('Deposit should be enabled.');
        }

        $.ajax({ 
            url: '/Commands/Deposit', 
            data: { account: self.account(), amount: self.amount() }, 
            success: function() { self.amount(0); }
            type: 'POST', 
            dataType: 'json' 
        });
    };
};

ko.applyBindings(new DepositViewModel());
Writing a test for this, it was obvious that I couldn't have my deposit function make requests directly. An abstraction that has served me well in the past, is a command executor. 
CommandExecutor = function() {
    this.execute = function(command, success) { };
};
We can have an implementation that handles each command individually, or we can have it send requests to our server by convention. The implementation below assumes that the name of our command has a corresponding endpoint on the server. 
CommandExecutor = function() {

    this.execute = function(command, success) {

        if (console) {
            console.log('Executing command..');
            console.log(command);
        }

        $.ajax({ 
            url: '/Commands/' + command.name, data: command.data, 
            success: success
            type: 'POST', dataType: 'json' 
        });
    };
};
While angular.js has dependency management built in, we can get away by injecting dependencies manually and a bit of bootstrapping - it's not that I often have large dependency graphs in the browser, or that I care much about the life cycles of my components.
var DepositViewModel = function(dependencies) {
    var self = this;

    self.account = ko.observable('');
    self.amount = ko.observable(0);

    self.depositEnabled = ko.computed(function() {
        return self.account() !== '' && self.amount() > 0;
    });
    
    self.deposit = function() {
        if (!self.depositEnabled()) {
            throw new Error('Deposit should be enabled.');
        }

        var command = { 
            name: 'Deposit', 
            data: { account: self.account(), amount: self.amount() } };
        var callback = function() { self.amount(0); };
        dependencies.commandExecutor.execute(command, callback);
    };
};

ko.applyBindings(new DepositViewModel({ commandExecutor: new CommandExecutor() }));
See, very little magic required.

Writing a test, we now only need to replace the command executor with an implementation that will record commands instead of actually sending them to the server.
var CommandExecutorMock = function () {

    var commands = [];

    this.execute = function (command, success) {
        commands.push(command);
        success();
    };
    this.verifyCommandWasExecuted = function(command) {
        for (var i = 0; i < commands.length; i++) {
            if (JSON.stringify(commands[i]) === JSON.stringify(command)) {
                return true;                        
            }
        }
        return false;
    };

};

describe("When a deposit is invoked", function () {
    var commandExecutor = new CommandExecutorMock();
    
    var model = new DepositViewModel({ commandExecutor: commandExecutor });
    model.account('MyAccount');
    model.amount(100);
    model.deposit();

    it("a deposit command is sent.", function() {
        var command = {
            name: 'Deposit', 
            data: { account: 'MyAccount', amount: 100 }
        };

        expect(commandExecutor.verifyCommandWasExecuted(command)).toBe(true);
    });  
});
I did something similar for queries, and ended up with not that much code, that didn't even take that long to write. I'm curious to see how this application will evolve.