Jumping off the couch and heading to MongoDB

It sucks to admit when you’ve made a bad decision, but step one is admitting you have a problem. My problem specifically was with what I wanted to accomplish and what CouchDB had to offer. To be clear the problem was with me and not CouchDB, its a great tool and resource for someone out there, but not for me.

context

One of my unpublished pets is a delicious clone ( live as of last weekend ) that was designed from month two to be a single user affair ( delicious data, custom spiders, reports, and a reddit cross-analysis ranking thing ). Delicious is/was a bookmarking website where you could apply arbitrary tags to bookmarks then retrieve all bookmarks related to a bookmark.

The data could be modeled as a URL has many tags and a tag has many urls. In SQL you could do something like

table BookMark:
url: text(255)
name: text(255)
date_created: text(255)

table Tags:
name: text(255)
date_created: text(255)

table BookMarks2Tags
tad_id: int
bookmark_id: int

Odd data, odd results

I can’t find the map logic I used, but the gist of it was that the results I getting back were
less then idea. It was easy to aggregate tag counts but to grab all bookmarks that had a specific tag was somewhat contorted.

Lack of straight forward documentation

Rechecking couchdb’s documentation website, I really hate information overload style doc’s. In the beginning I don’t care how something does what it does, just show me well documented examples of accomplishing the basics: Create, replace, update, delete. Probably immediately after that I’ll need how I can connect relate two entities of separate types and do CRUD on that. Rinse and repeat until I’ve made something so goddamn complicated that maybe its time to figure out how the whole mess works.

Error logging from hell

This could be the fault of the Ubuntu package manager for CouchDB or just my cluelessness, but I absolutely hate 5-10 page long exception traces that include a lot of stuff I don’t give a crap about… just tell me I’m an idiot and their’s a runtime syntax error on line two or the road peg doesn’t go in the square hole.

Lack of python support

To be fair, CouchDBKit rocks and did take some of the sting out of learning a new technology, but in earlier 2011 late 2010 I found the python CouchDB view interpreter left a lot to be desired ( partially due to CouchDB’s excessive error vomit traces ). Never mind that typing in whitespace sensitive code into a textarea field for adhoc query testing was entertaining.

Alright, I think I’m done ranting. Does this mean I’m going to completely swear off CouchDB? No. I keep proclaiming I’m never going to do anymore PHP contracts, and then the next thing you know I’m staring at an IDE full of PHP 5.0 ( for non PHP people PHP 5.0 was as good as MySQLDB 5.0… for non MySQL people, MySQL 5.0 was scary ).

HTML5 Canvas windowing proof of concept/prototype

Code is here ( https://gist.github.com/a17216d5b1db068ab41b )

Taking a break from a client project today and decided to try something real quick out. For one of my unpublished pet projects ( a near real time web based MUD ) I wanted a little map window to give visual feedback to the user on where exactly they were. Fortunately the Canvas API makes this stupid easy.

       var oX = this.player.x * (this.mMX / this.rMX);
    var oY = this.player.y * (this.mMX / this.rMY);
    
    var halfX = ( this.wMX / 2 );
    var halfY = ( this.wMY / 2 );
    
    var startX = Math.max(0, oX - halfX);
    var startY = Math.max(0, oY - halfY);
    
    var endX = Math.max(startX + this.wMX);
    var endY = Math.max(startY + this.wMY);
    
    var buffer = this.ctx.getImageData(startX, startY, endX, endY);
    this.window.putImageData(buffer, 0, 0);

First block takes the player or avatars position then scales up their grid position to the map canvas position.

Second block gets middle point of the window canvas, in this case if the window is 150×150, the origin is (75,75)

Now given the player’s position in the canvas map it finds the upper left and lower right corners of the map that is going to be copied from the map canvas into the window canvas. The Math.Max’s are there to prevent the upper left corner from being an impossible point (123, -50 ).

The end*’s use of Math.Max is actually crap on my part and isn’t needed.

Object oriented Javascript

Generally there is only two ways to make a “class” in Javascript. The first is the prototypical way


function Foo(){
      this.someProperty = "123";
}

Foo.prototype.bar = function(){
     console.log("howdy", this.someProperty);
}

var blah = new Foo();
Foo.someProperty = "Hello World!");
Foo.bar();
>>"Howdy", "Hello World"

or something like

   function Foo(){
       this.someProperty = 123;
       this.bar = function(){
              console.log("Howdy", this.someProperty);
       }
   }

It’s sometimes not trivial to choose one over the other. The prototypical path is a tad faster instantiating while the second can be easier to write, read, and maintain. Generally I chose the prototypical when I know I’ll be instantiating the desired object a lot ( thousands to tens or thousands of times ) while the second is preferred when I’m writing a more complicated object definition.

You’d think it would be slam dunk to always choose the closure ( 2nd variety ) but it has one major flaw, by itself, you cannot inherit a closure based class.

Fortunately its 2011 and at this point someone is guaranteed to have already run into the same problem. From my personnel experience, the first group that solved this problem was PrototypeJS and their class system, then I ran into ExtJS and their system. Great and all but what if I don’t want everything else that comes with these two frameworks?

No problem:
There’s the super diet solution offered by John Resig’s proof of concept Simple inheritence thing

and a much more advanced system called BaseJS by Dean Edwards ( http://code.google.com/p/base2/ ).

If I know a projects going to be somewhat involved I would go with investing in Base2JS but if not, John Regig’s script is good enough.

A better typeof for Javascript

If you know Javascript, then this isn’t a suprise:

typeof {a: 4}; //"object"
typeof [1, 2, 3]; //"object"
(function() {console.log(typeof arguments)})(); //object
typeof new ReferenceError; //"object"
typeof new Date; //"object"
typeof /a-z/; //"object"
typeof Math; //"object"
typeof JSON; //"object"
typeof new Number(4); //"object"
typeof new String("abc"); //"object"
typeof new Boolean(true); //"object"

But thanks to some dilligent work by one Angus Croll, you can do something like:

toType({a: 4}); //"object"
toType([1, 2, 3]); //"array"
(function() {console.log(toType(arguments))})(); //arguments
toType(new ReferenceError); //"error"
toType(new Date); //"date"
toType(/a-z/); //"regexp"
toType(Math); //"math"
toType(JSON); //"json"
toType(new Number(4)); //"number"
toType(new String("abc")); //"string"
toType(new Boolean(true)); //"boolean"

Check out the full explanation @
http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

Profiling tools for MongoDB

As MongoDb gains more customers, it will become increasing more important to be able to understand what the hell it is doing. I ran across this post this morning, it’s short but a good place to start in learning about profiling

The Python data model, an analogy

Given something like:

class Foo(object):
    pass

Define Foo.__init__ to determine how to define the interior of your instance.
Define Foo.__new__ to control how you instantiate Foo
Define a metaclass type.__new__ when you want to define what Foo is at run time.

Or put another way:
__init_ decides what the inside of the house looks like, Foo.__new__ decides how you enter your new house or if you even enter a new house at all. And then Type.__new__ and company let you decide what exactly Foo should look like at run time, before you even start instantiating a new Foo.

Stupid until proven otherwise

Feels like a life time ago, I was in the architect’s seat for a multi-million dollar proposed project. From my perspective I made several really damning design choices that I can only argue originated from my lack of more experience. Regardless of these mistakes, the team lead and the other code monkeys got the project off the floor and handling several thousands of concurrent requests/second without to much pain and suffering. So in the grand scheme I suppose the whole thing could be check on the plus column as a success.

Still, years later, my biggest mistake was abusing the crap out of data hiding in the form of protected/private parameters, guarded methods, and such… all because I didn’t trust the junior and mid-level dev’s to get it right. Because of these somewhat draconian design, the natural result was that the code monkeys worked around my restrictions at the cost of precious CPU cycles, extra memory, and some truly horrendous hacks. Sure as the architect I should have caught all of these things, but by that time I had become overbooked as lead on more critical projects while also being the acting DBA and sys. admin for everything ( except the obligatory exchange server which I successfully pretended didn’t exist ).

Thinking over how I would have handled things better, I think the over-arching gist of Alex Martelli’s presentation on API Anti-patterns from PyCon 2011 – http://vodpod.com/watch/5757194-pycon-2011-api-design-anti-patterns