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
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.
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.
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
And now imagine that the disk is full and write
fails, there is an asynchronous stack:
write
writeFile
copyFile
root
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