1. Dec 6th, 2011

    Rounded Corners 310 – Gangster

    Zero and one Fast, easy real-time metrics using Redis bitsets. A useful and often neglected data structure. Also, Redis has bitsets? How cool is that?

    Slow reading Nicholas Zakas investigates localStorage read performance and finds a lot more disk I/O than you’d imagine.

    Gangster The Awesome Node.js And Its Gang. Honored to have Zombie.js in that list.

    Spy games Solving the GCHQ challenge.

    Image perfect Instagram talk about their stack, running hundreds of servers on dozen of technologies.

    Smug report ”Yoda Conditions”, “Pokémon Exception Handling” and other programming classics.

  2. Dec 5th, 2011

    Rounded Corners 309 – Fucking descriptive variable names

    Related ql.io is relational algebra for Web service APIs. Pretty interesting concept.

    Surface area Node.js aesthetics.

    Refactor The NowJS team on why they threw out all their code (and you should too)

    Feeds Echo JS, a Hacker News-like site specifically for JavaScript. Built on LamerNews.

    Fast ten LinkedIn shares tips for keeping the fast in Node.js. Good stuff there.

    QotD Fucking Dev Tips:

    Using fucking descriptive variable names is way more important than saving a few fucking characters.

    Get your own AirCassette.

  3. Dec 2nd, 2011

    node-replay – record and replay HTTP responses like a boss

    Things that will ruin your day when tests make HTTP requests to other services:

    • That other service has the uptime of Twitter’s API
    • Network late ………… ncy
    • Being-rate limited and having to wait an hour for the next test run
    • Same request returns different result each time
    • Everyone else on the network is deep in BitTorrent terittory

    Things node-replay can do to make these problems go away:

    • Record API response once, replay as often as necessary
    • Stub HTTP requests (TBD)
    • Replay different responses to same request (great for testing error handling)
    • Not suck

    How to use node-replay

    Like this:

    $ npm install replay

    Now write some simple test case:

    assert = require("assert")
    http = require("http")
    replay = require("replay")
     
    http.get({ hostname: "www.iheartquotes.com", path: "/api/v1/random" }, function(response) {
      response.body = "";
      response.on("data", function(chunk) {
        response.body = response.body + chunk;
      })
      response.on("end", function() {
        // Now check the request we made to the I <3 Quotes API
        assert.equal(response.statusCode, 200);
        assert.equal(response.body, "Oxymoron 2. Exact estimate\n\n[codehappy] http://iheartquotes.com/fortune/show/38021\n");
        console.log("Woot!");
      })
    })

    This, of course, will fail the first time you run it. You’ll see:

    Error: Connection to http://www.iheartquotes.com:80/api/v1/random refused: not recording and no network access
      at Array.0 (/Users/assaf/projects/node-replay/lib/replay/proxy.coffee:87:21)
      at EventEmitter._tickCallback (node.js:192:40)

    Unless you tell it otherwise, node-replay runs in replay mode. In this mode it will replay any previously captured HTTP response, but it will not allow any outgoing network connection.

    That’s the default mode for running tests. “Why?” you ask. Good question. Running in replay mode forces any test you run to use recorded reponses, and so it will run (and fail or pass) the same way for anyone else, any other day of the week, on whatever hardware they use. Even if they’re on the AT&T network.

    Running in replay mode helps you write repeatable tests. Repeatable tests are a Good Thing.

    So the first thing you want to do to get that test to pass, is to run node-replay in record mode. In this mode it will replay any recorded response, but if no response was recorded, it will make a request to the server and capture the response.

    Let’s do that:

    $ REPLAY=record node test.js

    That wasn’t too hard, but the test is still failing. “How?” you must be wondering and scratching your head in total disbelief. It’s actually quite simple.

    Every request you make to ‘I 3> Quotes’ returns a different quote, and that test is looking for a very specific quote. So the test will fail, and each time fail with a different error.

    So one way we can fix this test is to change the assertion. Look at the error message, get the actual quote and make the assertion look for that value.

    Now run the test:

    $ node test.js
    Woot!

    Did the test pass? Of course it did. Run it again. Still passing? Why, yes.

    So let’s have a look at that captured response. All the respones recorded for ‘I ‘ will be listed here:

    $ ls fixtures/www.iheartquotes.com/

    There should be only one file there, since we only recorded one response. The file name is a timestamp, but feel free to rename it to something more rescriptive.

    The name of a response file doesn’t matter, it can be whatever you want. The name of the directory does, though, it matches the service hostname (and port when not 80).

    So that was one way to fix the failing test. Another one is to change the recorded response to match the assertion. Being able to edit (and create new) responses is quite important. Sometimes it’s the easiest way to create mock responses for testing, e.g. if you’re trying to test failure conditions that are hard to come by.

    So let’s edit the response file and change the body part, so the entire response reads like this:

    /api/v1/random
     
    200 HTTP/1.1
    server: nginx/0.7.67
    date: Fri, 02 Dec 2011 02:58:03 GMT
    content-type: text/plain
    etag: "a7131ebc1e81e43ea9ecf36fa2fdf610"
    cache-control: max-age=0, private, must-revalidate
     
    Oxymoron 2. Exact estimate
     
    [codehappy] http://iheartquotes.com/fortune/show/38021

    All responses are stored as text files using the simplest format ever, so you can edit them in Vim, or any of the many non-Vim text editors in existence:

    • First comes the request path (including query string)
    • Followed by any headers sent as part of the request (like Accept and Authorization)
    • Then an empty line
    • Next the response status code and (optional) HTTP version number
    • Followed by any headers sent as part of the response
    • Then another empty line
    • And the rest taken by the response body

    Settings

    We’ve got them. Just enough to make you happy and not enough to take all day to explain.

    The first and most obvious is the mode you run node-reply in:

    bloody – All requests go out, none get replayed. Use this if you want to remember what life was before you started using node-replay. Also, to test your code against changes to 3rd party API, because these do happen. Too often.

    cheat – Replays recorded responses, and allow HTTP outbound requests. This is mighty convenient when you’re writing new tests or changing code to make new, un-recorded HTTP requests, but you haven’t quite settled on which requets to make, so you don’t want any responses recorded quite yet.

    record – Replays recorded responses, or captures responses for future replay. Use this whenever you’re writing new tests or code that makes new HTTP requests.

    replay – Replays recorded responses, does not allow outbound requests. This is the default node. That’s another way of saying, “you’ll be running in this mode most of the time”.

    Of course, node-reply needs to store all those captured responses somewhere, and by default it will put them in the directory fixtures. Bet you have an idea for a better directory name. Easy to change.

    Like this:

    var replay = require("replay");
    replay.fixtures = __dirname + "/fixtures/replay"

    If you’re running into trouble, try turning debugging mode on. It helps. Sometimes.

    $ DEBUG=true node test.js
    Requesting http://www.iheartquotes.com:80/api/v1/random
    Woot!

    Geeking

    To make all that magic possible, node-replay replaces require('http').request with its own method. That method returns a ProxyRequest object that captures the request URL, headers and body.

    When it’s time to fire the request, it gets sent through a chain of proxies. The first proxy to have a response, returns it (via callback, this is Node.js after all). That terminates the chain. A proxy that doesn’t have a response still has to call the callback, but with no arguments. The request will then pass to the next proxy down the chain.

    The proxy chain looks something like this:

    • Logger dumps the request URL when running with DEBUG=true
    • The pass-through proxy will pass the request directly to the server in bloody mode, or when talking to localhost
    • The recorder proxy will either replay a captured request (if it has one), talk to the server and capture the response (in record mode), or pass to the next proxy
    • The pass-through proxy (2nd one) will pass the request to the server in cheat mode, return nothing in all other modes

    Loading pre-recorded responses to memory, from where they can be replayed, and storing new ones on disk, is handled by … cue big band … theCatalog.

    Enjoy.

  4. Nov 26th, 2011

    Rounded Corners 308 — Coffee delight

    Style Felix’s Node.js style guide is a good start. I follow most of these rules in my own projects.

    Eloquent Smooth CoffeeScript will teach you how to program, based on the wonderful (and highly recommended) Eloquent JavaScript. Worth a look.

    Flavors Yes, CoffeeScript is not JavaScript. But ECMAScript 6 could look very much like CoffeeScript. And in my book, that’s a good thing.

    Simple Genghis is a single-file MongoDB admin app.

    Faster When loading JavaScript, async is not enough: onload is your friend.

    Busted Apropos, congratulations to Node.js for breaking the Rails barrier.

    QotD Peter Skomoroch:

    “Do or Do not. There is no multiple planning meetings to discuss possibilities of try” – Yoda

  5. Nov 24th, 2011

    Side dish of Poutine

    This is a new project Jerome and I are working on. It’s still not close to completion, but I thought I’d give you a taste. Just to whet your appetite and get some feedback.

    It started by looking at the libraries out there that let you use MongoDB with Node.js, and realizing they’re all quite bad. They work, that’s for sure, and bugs get fixed. But when we write application code using these APIs, well … it’s just not code we want to look at all day and maintain.

    So we re-imagined what a kick-ass Node.js object mapper for MongoDB would look like. And it all starts with: “does this make my code easier to write, test and maintain”?

    Here’s a sample, I’ll let you be the judge:

    class User extends Model
      @collection "users"
     
      @field "name", String
     
      @field "password", String
      @set "password", (clear)->
        @_.password = crypt(clear)
     
      @field "email", String
     
      @get "posts", ->
        Post.where(author_id: @_id)
     
    # me is a scope
    me = User.where(name: "Assaf")
    me.one (error, user)->
      console.log "Loaded #{user.name}"
      user.posts.count (error, count)->
        console.log "Published #{count} posts"

    We started with three principles. The first one is progressive enhancement.

    Working at the driver level is OK, and in fact, for some things the better choice. But it’s also great to have more capable model objects that encapsulate data and business logic. I’ve worked with different database servers to realize that for most applications both are necessary.

    I also noticed how most drivers are too low-level and hard to use, with APIs that leak the underlying network protocol. That ends up pushing developers to do all their work with the more friendly, better-designed ORM/ODM. Even the stuff ORM/ODM clearly sucks at.

    Why does it have to be one or the other? Why can’t you work at the driver level when you need to, and work with models when it’s easier to? Why can’t you do both with the same, well designed API?

    What if this gave you driver-level performance:

    collection("posts").where(category: "db").all (error, posts)->
     
      # These posts are POJOs
      for post in posts
        console.log "Loaded #{post.title}"

    And this gave you model objects, with schema, before/after hooks, validations, and all other good things:

    collection(Post).where(category: "db").all (error, posts)->
      # These posts are model objects
      for post in posts
        console.log "Loaded #{post.title}"

    It’s practically the same API, but can take advantage of model objects when you tell the collection to use one. And we let you bring your own model implementation if you don’t like ours. This reminds me of CSS, where some rules only apply to more modern browsers. Progressive enhancement.

    Did you notice, we care a lot about code readability? After all we spend more time reading code than typing it in. So not surprising, the second principle is readability. The readability of the code you’ll be writing when using the API.

    It turns out CoffeeScript allows you to call methods on a class (more specifically, the constructor function) from within the class definition. Quite a nifty feature if you write a lot of application code in CoffeeScript.

    It lets your write this:

    class Post extends Model
    @collection "posts"
     
    # -- Title stuff --
    @field "title", String
     
    random: ->
    @title = sampleTitles.atRandom()
     
    @validate ->
    assert @title, "Missing title"

    I personally like organizing larger models into groups of related fields/behaviors. For example, a use model would have one section dealing with credentials, another with profile display, another with usage metric. Being able to mix meta-data methods with method definitions makes that easy.

    Another way we care about readability of your code, we’re very conservative with what methods we put in the Model class. Only the methods we think you’ll want to use, like field and validate. Everything else is tucked away in a separate namespace. The idea of working with a base class that holds 100′s of implementation methods is an anti-pattern.

    The third principle deals with giving you just the right level of control. And by that I mean taking care of as many details as possible, and picking the best possible defaults. But also realizing that sometimes you need finer control, making that possible, and teaching you when and how to take action.

    For example, I’ve seen a few code bases that run an entire application using a single MongoDB connection. That works since the driver can make sense of requests sent/received concurrently, but it’s only using on server thread, so all operations are serialized and you’re not getting much performance out of MongoDB.

    You could open one connection per request, but a Node.js Web server can easily scale to thousands of those, MongoDB can barely handle hundreds. So we put a connection pool in there, and it works behind the scene and dispatches each request to the next available connection. Whether you use one connection in the entire application, or one for each request, your code will use as many connections as the pool allows. You don’t have to worry about a thing.

    Except when you do. In some cases you need a sequence of requests to go over the same underlying TCP connection. So we made that possible as well, and we documented the hell out of it, so you’ll know when and how to use this.

    These are just examples, we’re not done yet, but I think you’ll agree, we’re off to a great start.

  6. Nov 21st, 2011

    Rounded Corners 307 – API love & hate

    Love How to make people using your API love you.

    Hate APIs are pain. But that’s just a prequel to an upcoming solution.

    Documented How to write a README:

    TL;DR
    If nothing else, write an example.

    Degraded It’s trade-offs all the way down. WebSocket fallbacks:

    This leads to my next point – if scalability is your concern, graceful degradation may just be sufficient in a lot of use cases.

    Gossip Using Gossip Protocols For Failure Detection, Monitoring, Messaging And Other Good Things.

    Disaster porn DTrace and post-morten debugging for Node.js.

    Biased I don’t always read TechCrunch, but when I do, it’s because Eric Ries has something worthwhile to say. On Racism and Meritocracy:

    And what the grownups have discovered, through painstaking research, is that it is extremely easy forsystems to become biased, even if none of the individual people in those systems intends to be biased. This is partly a cognitive problem, that people harbor unconscious bias, and partly an organizational problem, that even a collection of unbiased actors can work together to accidentally create a biased system. And when those systems are examined scientifically, they can be reformed to reduce their bias.


  7. Nov 20th, 2011

    Less to spend, but most important, less to waste

    What is wrong with AMQP is an epic (read: way too long) rant about the standards sausage factory, specifically AMQP.

    I skimmed, but I love this part:

    In my view, the first problem is that AMQP has been positioned as an “Enterprise Technology”. What does this mean? I think the intention is that technology is like air travel, which is segmented into a cheap, sterile, tiresome, squashed experience for the ordinary jeans-and-sneakers proles, and an expensive, luxurious VIP experience for the high-value suits. You have ordinary prole technology, and then you have Enterprise Technology. AMQP has to be the very best, since it’s going to be used in banks and so on. You would not want your pension to be lost thanks to a missing transaction. AMQP users are VIPs, and intend to travel Business Class. Both customers and suppliers prefer the luxury route: it means bigger budgets, and more air miles.

    Now this may make sense in air travel, but as far as I can see in the software world, the prole technology is generally better, faster, more secure, more robust, and above all, simpler. Proles have less money to spend, but most importantly, less money to waste.

     

  8. Nov 19th, 2011

    Rounded Corners 306 – Polyglot

    Simplified Google Calendar API goes to version V3. Out: XML, unnecessary Atom, namespaces, and that weird authentication scheme. In: JSON, OAuth 2, PATCH support and a whole lot of simplicity.

    Tested Travis CI now supports Node.js as first-class language. Here’s how to test Node.js modules using Travis.

    Storage Polyglot Persistence:

    This polyglot affect will be apparent even within a single application. A complex enterprise application uses different kinds of data, and already usually integrates information from different sources. Increasingly we’ll see such applications manage their own data using different technologies depending on how the data is used.

    Hardcore The lockless memory allocator.

    Futuretech And just as good, emerging trends in Web development:

    Patterns are the new gradients.
    Square is the new rounded.
    Keyboard shortcuts are the new not having keyboard shortcuts.

    QotD Patrick McKenzie:

    I once knew a company with a problem. So they outsourced. Now they have 10 problems but are only paying for 2.5.

  9. Nov 18th, 2011

    Rounded Corners 305 – We’ve got great backing

    Can’t wait The Node.js 0.8 roadmap got isolates, I/O domains and a better allocator.

    Timed Measuring network latency using JavaScript and the DOM. Also, a good read about network latency in the browser.

    Valuable Overview of what’s new in CSS3 values and units.

    iPhone only How to add bookmarks to the home screen for quick access to various settings panes.

    Comic relief A delightful Tumblr or mobile Web WTFs.

    Translated Startups say the darndest things, a helpful translation cheat sheet:

    “We’ve got great backing”
    We managed to convince VCs to give us money but we haven’t convinced any actual customers to do so.

    QtoD Kent Beck:

    if deploying after the first 10% of your project is done wouldn’t teach you anything, you worked on the wrong 10%

  10. Nov 14th, 2011

    Rounded Corners 304 – Save for later

    Save for later New and improved page explaining Redis persistence options: when and how to use RDB and AOF. Related, the short-term plans towards Redis 2.6. But if you’re not already using Redis, check out Zero to Master in 30 minutes.

    Location, location, location jQuery address picker plugin and a re-design of the country selector.

    Rings true Conspiracy theory no 1.

    Decorative Our Pointless Pursuit of Semantic Value is a good read on the difference between useful and decorative HTML semantic elements.

    Long term On long roadmaps:

    The best founders have these long roadmaps.  If they can stay engaged in their companies, they can realize them over extended periods of time.

    Always be testing A surprising A/B test result.

    QotD Marco Rogers:

    I wonder how many nerd arguments ultimately boil down to what level of abstraction you’re personally comfortable with. My guess is lots.