Skip to content

Instantly share code, notes, and snippets.

@piscisaureus
Created May 28, 2014 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piscisaureus/8ba70c7648d63ce120a8 to your computer and use it in GitHub Desktop.
Save piscisaureus/8ba70c7648d63ce120a8 to your computer and use it in GitHub Desktop.

Introducing zones.

Before we get started: 'zone' is a library that makes programming with node much easier. It's work in progress, but you can try it out now.

You get goodies like:

  • Automatic exception handling
  • Long stack traces
  • Detect and handle common pitfalls with callbacks

Asynchronous composition

Think of the fs.readFile(filename, cb) asynchronous function that's part of node.js API. You could imagine that when you call that function a "read file" operation is started, and your callback is called when it is done.

But reading a file in it's entirety isn't actually a single syscall; the fs.readFile function actually calls a couple of other asynchronous functions (that are actual syscalls) like fs.open(filename, mode, fd), and also fs.fstat(), fs.read() and fs.close(). After you call fs.readFile(), node.js is not aware that there is a readFile operation pending. That "read file" operation exists only in your head - Node just knows about the primitives that it's implemented with.

That's painful because fs.readfile needs to be super careful to clean up after itself when any of these primitives (open, fstat, read, close) fail. It also must be careful to not accidentally call the callback twice, or never, or leak the file descriptor that's been opened.

Enter zones.

Zones

The zone library let's you group resources and asynchronous operations that are part of a more high-level asynchronous operation. Such a group can - as a whole - have a callback. When you create zones, node.js now has much more understanding of what you're trying to accomplish, instead of only knowing about the primitives you're using.

That let's it do more things for you so: it can automatically clean up resources on errors because it knows which resources are related. It can route exceptions the right way, and enforce contracts related to calling callbacks. It can tell you what's going on in your node application while it's running.

fs.readFile doesn't use the zone library. It probably should, that'd fix for example this bug. The implementation could also be much simpler.

Zones are composable

Of course you can also compose zones to form even more high-level operations. A readFile and a writeFile operations could together form a copyFile zone. Now we can build a tree of what's going on in our process:

root
  \ copyfile
      + readFile
      |   + open
      |   + read
      \ writeFile
          + open
          \ write

Asynchronous stack trace

And now imagine that the disk is full and write fails, there is an asynchronous stack:

write
writeFile
copyFile
root

Using zones

Getting started with zones is really easy. The most important thing you have to do is enable zones.

require('zone').enable();

This makes available a global called zone which always points at the active zone. Now you can use the different methods on the zone object to create zones:

zone.create(function MyZone() {
  setTimeout(function() {
    zone.return(42);
  });
}).setCallback(function(err, result) {
  console.log('The answer is %d', result);
});

Bla bla bla

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment