395 lines
16 KiB
HTML
395 lines
16 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Domain Node.js v0.8.14 Manual & Documentation</title>
|
|
<link rel="stylesheet" href="assets/style.css">
|
|
<link rel="stylesheet" href="assets/sh.css">
|
|
<link rel="canonical" href="http://nodejs.org/api/domain.html">
|
|
</head>
|
|
<body class="alt apidoc" id="api-section-domain">
|
|
<div id="intro" class="interior">
|
|
<a href="/" title="Go back to the home page">
|
|
<img id="logo" src="http://nodejs.org/images/logo-light.png" alt="node.js">
|
|
</a>
|
|
</div>
|
|
<div id="content" class="clearfix">
|
|
<div id="column2" class="interior">
|
|
<ul>
|
|
<li><a href="/" class="home">Home</a></li>
|
|
<li><a href="/download/" class="download">Download</a></li>
|
|
<li><a href="/about/" class="about">About</a></li>
|
|
<li><a href="http://search.npmjs.org/" class="npm">npm Registry</a></li>
|
|
<li><a href="http://nodejs.org/api/" class="docs current">Docs</a></li>
|
|
<li><a href="http://blog.nodejs.org" class="blog">Blog</a></li>
|
|
<li><a href="/community/" class="community">Community</a></li>
|
|
<li><a href="/logos/" class="logos">Logos</a></li>
|
|
<li><a href="http://jobs.nodejs.org/" class="jobs">Jobs</a></li>
|
|
</ul>
|
|
<p class="twitter"><a href="http://twitter.com/nodejs">@nodejs</a></p>
|
|
</div>
|
|
|
|
<div id="column1" class="interior">
|
|
<header>
|
|
<h1>Node.js v0.8.14 Manual & Documentation</h1>
|
|
<div id="gtoc">
|
|
<p>
|
|
<a href="index.html" name="toc">Index</a> |
|
|
<a href="all.html">View on single page</a> |
|
|
<a href="domain.json">View as JSON</a>
|
|
</p>
|
|
</div>
|
|
<hr>
|
|
</header>
|
|
|
|
<div id="toc">
|
|
<h2>Table of Contents</h2>
|
|
<ul>
|
|
<li><a href="#domain_domain">Domain</a><ul>
|
|
<li><a href="#domain_additions_to_error_objects">Additions to Error objects</a></li>
|
|
<li><a href="#domain_implicit_binding">Implicit Binding</a></li>
|
|
<li><a href="#domain_explicit_binding">Explicit Binding</a></li>
|
|
<li><a href="#domain_domain_create">domain.create()</a></li>
|
|
<li><a href="#domain_class_domain">Class: Domain</a><ul>
|
|
<li><a href="#domain_domain_run_fn">domain.run(fn)</a></li>
|
|
<li><a href="#domain_domain_members">domain.members</a></li>
|
|
<li><a href="#domain_domain_add_emitter">domain.add(emitter)</a></li>
|
|
<li><a href="#domain_domain_remove_emitter">domain.remove(emitter)</a></li>
|
|
<li><a href="#domain_domain_bind_callback">domain.bind(callback)</a><ul>
|
|
<li><a href="#domain_example">Example</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#domain_domain_intercept_callback">domain.intercept(callback)</a><ul>
|
|
<li><a href="#domain_example_1">Example</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#domain_domain_dispose">domain.dispose()</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<div id="apicontent">
|
|
<h1>Domain<span><a class="mark" href="#domain_domain" id="domain_domain">#</a></span></h1>
|
|
<pre><code>Stability: 1 - Experimental</code></pre>
|
|
<p>Domains provide a way to handle multiple different IO operations as a
|
|
single group. If any of the event emitters or callbacks registered to a
|
|
domain emit an <code>error</code> event, or throw an error, then the domain object
|
|
will be notified, rather than losing the context of the error in the
|
|
<code>process.on('uncaughtException')</code> handler, or causing the program to
|
|
exit with an error code.
|
|
|
|
</p>
|
|
<p>This feature is new in Node version 0.8. It is a first pass, and is
|
|
expected to change significantly in future versions. Please use it and
|
|
provide feedback.
|
|
|
|
</p>
|
|
<p>Due to their experimental nature, the Domains features are disabled unless
|
|
the <code>domain</code> module is loaded at least once. No domains are created or
|
|
registered by default. This is by design, to prevent adverse effects on
|
|
current programs. It is expected to be enabled by default in future
|
|
Node.js versions.
|
|
|
|
</p>
|
|
<h2>Additions to Error objects<span><a class="mark" href="#domain_additions_to_error_objects" id="domain_additions_to_error_objects">#</a></span></h2>
|
|
<!-- type=misc -->
|
|
|
|
<p>Any time an Error object is routed through a domain, a few extra fields
|
|
are added to it.
|
|
|
|
</p>
|
|
<ul>
|
|
<li><code>error.domain</code> The domain that first handled the error.</li>
|
|
<li><code>error.domain_emitter</code> The event emitter that emitted an 'error' event
|
|
with the error object.</li>
|
|
<li><code>error.domain_bound</code> The callback function which was bound to the
|
|
domain, and passed an error as its first argument.</li>
|
|
<li><code>error.domain_thrown</code> A boolean indicating whether the error was
|
|
thrown, emitted, or passed to a bound callback function.</li>
|
|
</ul>
|
|
<h2>Implicit Binding<span><a class="mark" href="#domain_implicit_binding" id="domain_implicit_binding">#</a></span></h2>
|
|
<!--type=misc-->
|
|
|
|
<p>If domains are in use, then all new EventEmitter objects (including
|
|
Stream objects, requests, responses, etc.) will be implicitly bound to
|
|
the active domain at the time of their creation.
|
|
|
|
</p>
|
|
<p>Additionally, callbacks passed to lowlevel event loop requests (such as
|
|
to fs.open, or other callback-taking methods) will automatically be
|
|
bound to the active domain. If they throw, then the domain will catch
|
|
the error.
|
|
|
|
</p>
|
|
<p>In order to prevent excessive memory usage, Domain objects themselves
|
|
are not implicitly added as children of the active domain. If they
|
|
were, then it would be too easy to prevent request and response objects
|
|
from being properly garbage collected.
|
|
|
|
</p>
|
|
<p>If you <em>want</em> to nest Domain objects as children of a parent Domain,
|
|
then you must explicitly add them, and then dispose of them later.
|
|
|
|
</p>
|
|
<p>Implicit binding routes thrown errors and <code>'error'</code> events to the
|
|
Domain's <code>error</code> event, but does not register the EventEmitter on the
|
|
Domain, so <code>domain.dispose()</code> will not shut down the EventEmitter.
|
|
Implicit binding only takes care of thrown errors and <code>'error'</code> events.
|
|
|
|
</p>
|
|
<h2>Explicit Binding<span><a class="mark" href="#domain_explicit_binding" id="domain_explicit_binding">#</a></span></h2>
|
|
<!--type=misc-->
|
|
|
|
<p>Sometimes, the domain in use is not the one that ought to be used for a
|
|
specific event emitter. Or, the event emitter could have been created
|
|
in the context of one domain, but ought to instead be bound to some
|
|
other domain.
|
|
|
|
</p>
|
|
<p>For example, there could be one domain in use for an HTTP server, but
|
|
perhaps we would like to have a separate domain to use for each request.
|
|
|
|
</p>
|
|
<p>That is possible via explicit binding.
|
|
|
|
</p>
|
|
<p>For example:
|
|
|
|
</p>
|
|
<pre><code>// create a top-level domain for the server
|
|
var serverDomain = domain.create();
|
|
|
|
serverDomain.run(function() {
|
|
// server is created in the scope of serverDomain
|
|
http.createServer(function(req, res) {
|
|
// req and res are also created in the scope of serverDomain
|
|
// however, we'd prefer to have a separate domain for each request.
|
|
// create it first thing, and add req and res to it.
|
|
var reqd = domain.create();
|
|
reqd.add(req);
|
|
reqd.add(res);
|
|
reqd.on('error', function(er) {
|
|
console.error('Error', er, req.url);
|
|
try {
|
|
res.writeHead(500);
|
|
res.end('Error occurred, sorry.');
|
|
res.on('close', function() {
|
|
// forcibly shut down any other things added to this domain
|
|
reqd.dispose();
|
|
});
|
|
} catch (er) {
|
|
console.error('Error sending 500', er, req.url);
|
|
// tried our best. clean up anything remaining.
|
|
reqd.dispose();
|
|
}
|
|
});
|
|
}).listen(1337);
|
|
});</code></pre>
|
|
<h2>domain.create()<span><a class="mark" href="#domain_domain_create" id="domain_domain_create">#</a></span></h2>
|
|
<div class="signature"><ul>
|
|
<li>return: <span class="type">Domain</span></li>
|
|
</div></ul>
|
|
<p>Returns a new Domain object.
|
|
|
|
</p>
|
|
<h2>Class: Domain<span><a class="mark" href="#domain_class_domain" id="domain_class_domain">#</a></span></h2>
|
|
<p>The Domain class encapsulates the functionality of routing errors and
|
|
uncaught exceptions to the active Domain object.
|
|
|
|
</p>
|
|
<p>Domain is a child class of <a href="events.html#events_class_events_eventemitter">EventEmitter</a>. To handle the errors that it
|
|
catches, listen to its <code>error</code> event.
|
|
|
|
</p>
|
|
<h3>domain.run(fn)<span><a class="mark" href="#domain_domain_run_fn" id="domain_domain_run_fn">#</a></span></h3>
|
|
<div class="signature"><ul>
|
|
<li><code>fn</code> <span class="type">Function</span></li>
|
|
</div></ul>
|
|
<p>Run the supplied function in the context of the domain, implicitly
|
|
binding all event emitters, timers, and lowlevel requests that are
|
|
created in that context.
|
|
|
|
</p>
|
|
<p>This is the most basic way to use a domain.
|
|
|
|
</p>
|
|
<p>Example:
|
|
|
|
</p>
|
|
<pre><code>var d = domain.create();
|
|
d.on('error', function(er) {
|
|
console.error('Caught error!', er);
|
|
});
|
|
d.run(function() {
|
|
process.nextTick(function() {
|
|
setTimeout(function() { // simulating some various async stuff
|
|
fs.open('non-existent file', 'r', function(er, fd) {
|
|
if (er) throw er;
|
|
// proceed...
|
|
});
|
|
}, 100);
|
|
});
|
|
});</code></pre>
|
|
<p>In this example, the <code>d.on('error')</code> handler will be triggered, rather
|
|
than crashing the program.
|
|
|
|
</p>
|
|
<h3>domain.members<span><a class="mark" href="#domain_domain_members" id="domain_domain_members">#</a></span></h3>
|
|
<div class="signature"><ul>
|
|
<li><span class="type">Array</span></li>
|
|
</div></ul>
|
|
<p>An array of timers and event emitters that have been explicitly added
|
|
to the domain.
|
|
|
|
</p>
|
|
<h3>domain.add(emitter)<span><a class="mark" href="#domain_domain_add_emitter" id="domain_domain_add_emitter">#</a></span></h3>
|
|
<div class="signature"><ul>
|
|
<li><code>emitter</code> <span class="type">EventEmitter | Timer</span> emitter or timer to be added to the domain</li>
|
|
</div></ul>
|
|
<p>Explicitly adds an emitter to the domain. If any event handlers called by
|
|
the emitter throw an error, or if the emitter emits an <code>error</code> event, it
|
|
will be routed to the domain's <code>error</code> event, just like with implicit
|
|
binding.
|
|
|
|
</p>
|
|
<p>This also works with timers that are returned from <code>setInterval</code> and
|
|
<code>setTimeout</code>. If their callback function throws, it will be caught by
|
|
the domain 'error' handler.
|
|
|
|
</p>
|
|
<p>If the Timer or EventEmitter was already bound to a domain, it is removed
|
|
from that one, and bound to this one instead.
|
|
|
|
</p>
|
|
<h3>domain.remove(emitter)<span><a class="mark" href="#domain_domain_remove_emitter" id="domain_domain_remove_emitter">#</a></span></h3>
|
|
<div class="signature"><ul>
|
|
<li><code>emitter</code> <span class="type">EventEmitter | Timer</span> emitter or timer to be removed from the domain</li>
|
|
</div></ul>
|
|
<p>The opposite of <code>domain.add(emitter)</code>. Removes domain handling from the
|
|
specified emitter.
|
|
|
|
</p>
|
|
<h3>domain.bind(callback)<span><a class="mark" href="#domain_domain_bind_callback" id="domain_domain_bind_callback">#</a></span></h3>
|
|
<div class="signature"><ul>
|
|
<li><code>callback</code> <span class="type">Function</span> The callback function</li>
|
|
<li>return: <span class="type">Function</span> The bound function</li>
|
|
</div></ul>
|
|
<p>The returned function will be a wrapper around the supplied callback
|
|
function. When the returned function is called, any errors that are
|
|
thrown will be routed to the domain's <code>error</code> event.
|
|
|
|
</p>
|
|
<h4>Example<span><a class="mark" href="#domain_example" id="domain_example">#</a></span></h4>
|
|
<pre><code>var d = domain.create();
|
|
|
|
function readSomeFile(filename, cb) {
|
|
fs.readFile(filename, 'utf8', d.bind(function(er, data) {
|
|
// if this throws, it will also be passed to the domain
|
|
return cb(er, data ? JSON.parse(data) : null);
|
|
}));
|
|
}
|
|
|
|
d.on('error', function(er) {
|
|
// an error occurred somewhere.
|
|
// if we throw it now, it will crash the program
|
|
// with the normal line number and stack message.
|
|
});</code></pre>
|
|
<h3>domain.intercept(callback)<span><a class="mark" href="#domain_domain_intercept_callback" id="domain_domain_intercept_callback">#</a></span></h3>
|
|
<div class="signature"><ul>
|
|
<li><code>callback</code> <span class="type">Function</span> The callback function</li>
|
|
<li>return: <span class="type">Function</span> The intercepted function</li>
|
|
</div></ul>
|
|
<p>This method is almost identical to <code>domain.bind(callback)</code>. However, in
|
|
addition to catching thrown errors, it will also intercept <code>Error</code>
|
|
objects sent as the first argument to the function.
|
|
|
|
</p>
|
|
<p>In this way, the common <code>if (er) return callback(er);</code> pattern can be replaced
|
|
with a single error handler in a single place.
|
|
|
|
</p>
|
|
<h4>Example<span><a class="mark" href="#domain_example_1" id="domain_example_1">#</a></span></h4>
|
|
<pre><code>var d = domain.create();
|
|
|
|
function readSomeFile(filename, cb) {
|
|
fs.readFile(filename, 'utf8', d.intercept(function(data) {
|
|
// note, the first argument is never passed to the
|
|
// callback since it is assumed to be the 'Error' argument
|
|
// and thus intercepted by the domain.
|
|
|
|
// if this throws, it will also be passed to the domain
|
|
// so the error-handling logic can be moved to the 'error'
|
|
// event on the domain instead of being repeated throughout
|
|
// the program.
|
|
return cb(null, JSON.parse(data));
|
|
}));
|
|
}
|
|
|
|
d.on('error', function(er) {
|
|
// an error occurred somewhere.
|
|
// if we throw it now, it will crash the program
|
|
// with the normal line number and stack message.
|
|
});</code></pre>
|
|
<h3>domain.dispose()<span><a class="mark" href="#domain_domain_dispose" id="domain_domain_dispose">#</a></span></h3>
|
|
<p>The dispose method destroys a domain, and makes a best effort attempt to
|
|
clean up any and all IO that is associated with the domain. Streams are
|
|
aborted, ended, closed, and/or destroyed. Timers are cleared.
|
|
Explicitly bound callbacks are no longer called. Any error events that
|
|
are raised as a result of this are ignored.
|
|
|
|
</p>
|
|
<p>The intention of calling <code>dispose</code> is generally to prevent cascading
|
|
errors when a critical part of the Domain context is found to be in an
|
|
error state.
|
|
|
|
</p>
|
|
<p>Once the domain is disposed the <code>dispose</code> event will emit.
|
|
|
|
</p>
|
|
<p>Note that IO might still be performed. However, to the highest degree
|
|
possible, once a domain is disposed, further errors from the emitters in
|
|
that set will be ignored. So, even if some remaining actions are still
|
|
in flight, Node.js will not communicate further about them.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="footer">
|
|
<ul class="clearfix">
|
|
<li><a href="/">Node.js</a></li>
|
|
<li><a href="/download/">Download</a></li>
|
|
<li><a href="/about/">About</a></li>
|
|
<li><a href="http://search.npmjs.org/">npm Registry</a></li>
|
|
<li><a href="http://nodejs.org/api/">Docs</a></li>
|
|
<li><a href="http://blog.nodejs.org">Blog</a></li>
|
|
<li><a href="/community/">Community</a></li>
|
|
<li><a href="/logos/">Logos</a></li>
|
|
<li><a href="http://jobs.nodejs.org/">Jobs</a></li>
|
|
<li><a href="http://twitter.com/nodejs" class="twitter">@nodejs</a></li>
|
|
</ul>
|
|
|
|
<p>Copyright <a href="http://joyent.com/">Joyent, Inc</a>, Node.js is a <a href="/trademark-policy.pdf">trademark</a> of Joyent, Inc. View <a href="https://raw.github.com/joyent/node/v0.8.14/LICENSE">license</a>.</p>
|
|
</div>
|
|
|
|
<script src="../sh_main.js"></script>
|
|
<script src="../sh_javascript.min.js"></script>
|
|
<script>highlight(undefined, undefined, 'pre');</script>
|
|
<script>
|
|
window._gaq = [['_setAccount', 'UA-10874194-2'], ['_trackPageview']];
|
|
(function(d, t) {
|
|
var g = d.createElement(t),
|
|
s = d.getElementsByTagName(t)[0];
|
|
g.src = '//www.google-analytics.com/ga.js';
|
|
s.parentNode.insertBefore(g, s);
|
|
}(document, 'script'));
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|