Fork & Extend vs. Build Your Own, a NodeJS Example
For Hot or Not, I wanted to leverage as much existing code (open-source libraries) as possible, so I could focus on the more interesting application logic. I found a library to work with the database (RRD), but there were a few things about it that didn’t fit my needs, so I ended up releasing a new library. What follows are the reasons I decided to build my own solution, and the downsides to that course of action.
The Existing Library When looking for a javascript library, the one that seemed closest to what I needed was javascript-rrd. It’s intended for client-side use, and includes a bunch of extra code for generating graphs in the browser (which doesn’t seem terribly inappropriate considering that librrd also comes with graphing tools). There were two issues, though, that prevented me from moving forward with the library as-is.
Issue #1: Completeness The Problem: The existing library is good at querying a database, but doesn’t support manipulation (updating, importing), which was required for my project.
The Solution: I forked the project on github, and started adding what I needed. I didn’t follow the pure-javascript pattern used in the existing code, but instead went with the much-simpler-but-not-as-cool pattern of shelling out to the rrdtool program.
Issue #2: Portability The Problem: The existing implementation was pure javascript (it parsed the binary database file without the help of librrd). The problem with that is that RRDs are not portable; the internal binary format may change from one platform to another, which means that the library was not necessarily portable. I like the idea of not relying on librrd, but 1) that makes for a lot more code, and 2) you have to manage the portability issue yourself (or, in this case, not manage it).
The Solution: I ended up creating a new project (as opposed to my fork of the existing one). I pulled my few added features over, and replaced the existing library’s functionality to now rely on rrdtool. The lines of code dropped from 2300 to 86. (I also implemented the new library in coffeescript, which helps.)
Downsides rrdtool: rrdtool comes with a library that provides the same set of features as the tool (librrd). It would have been cleaner to use the library, rather than shelling out, but the documentation for the library is essentially empty. It suggests that the reader just dig through the C code to figure it out, which was well beyond my pain-threshold for this project. I also don’t have any idea how hard it is to use a C library from nodejs, and that may well also be beyond my pain-threshold, but I would’ve at least explored it if the docs were better.
Testing: I did include vows tests with the project, but the tests are a little sparse (mostly due to my struggling with vows, probably because of my lack of familiarity with it). I struggled a lot with asynchronous testing in vows & coffeescript.
Completeness: While my particular needs are met by the project as-is, there are definitely some gaps and rough edges that will have to be addressed before this is a fully robustified library.
Conclusion I generally tend to err on the side of build-it-yourself, and I waste a ton of time by not relying more on existing libraries (I’m trying to get better about this). For this particular case, the portability and lines of code improvements seem fairly strong arguments to me for a non-pure-js solution in coffeescript.
Getting the Code NPM: You can get the package using npm install rrd
Github: The code is also available on github.