Skip to content

Commit

Permalink
domain: remove .dispose()
Browse files Browse the repository at this point in the history
`domain.dispose()` is generally considered an anti-pattern, has been
runtime-deprecated for over 4 years, and is a part of the `domain`
module that can not be emulated by `async_hooks`; so remove it.

Ref: https://nodejs.org/en/docs/guides/domain-postmortem/
Ref: 4a74fc9

PR-URL: #15412
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
  • Loading branch information
addaleax authored and BridgeAR committed Sep 20, 2017
1 parent 750c080 commit 602fd36
Show file tree
Hide file tree
Showing 12 changed files with 17 additions and 336 deletions.
4 changes: 2 additions & 2 deletions doc/api/deprecations.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ instead.
<a id="DEP0012"></a> <a id="DEP0012"></a>
### DEP0012: Domain.dispose ### DEP0012: Domain.dispose


Type: Runtime Type: End-of-Life


[`Domain.dispose()`][] is deprecated. Recover from failed I/O actions [`Domain.dispose()`][] is removed. Recover from failed I/O actions
explicitly via error event handlers set on the domain instead. explicitly via error event handlers set on the domain instead.


<a id="DEP0013"></a> <a id="DEP0013"></a>
Expand Down
18 changes: 1 addition & 17 deletions doc/api/domain.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ added.


Implicit binding routes thrown errors and `'error'` events to the Implicit binding routes thrown errors and `'error'` events to the
Domain's `'error'` event, but does not register the EventEmitter on the Domain's `'error'` event, but does not register the EventEmitter on the
Domain, so [`domain.dispose()`][] will not shut down the EventEmitter. Domain.
Implicit binding only takes care of thrown errors and `'error'` events. Implicit binding only takes care of thrown errors and `'error'` events.


## Explicit Binding ## Explicit Binding
Expand Down Expand Up @@ -329,15 +329,6 @@ d.on('error', (er) => {
}); });
``` ```


### domain.dispose()

> Stability: 0 - Deprecated. Please recover from failed IO actions
> explicitly via error event handlers set on the domain.
Once `dispose` has been called, the domain will no longer be used by callbacks
bound into the domain via `run`, `bind`, or `intercept`, and a `'dispose'` event
is emitted.

### domain.enter() ### domain.enter()


The `enter` method is plumbing used by the `run`, `bind`, and `intercept` The `enter` method is plumbing used by the `run`, `bind`, and `intercept`
Expand All @@ -351,9 +342,6 @@ Calling `enter` changes only the active domain, and does not alter the domain
itself. `enter` and `exit` can be called an arbitrary number of times on a itself. `enter` and `exit` can be called an arbitrary number of times on a
single domain. single domain.


If the domain on which `enter` is called has been disposed, `enter` will return
without setting the domain.

### domain.exit() ### domain.exit()


The `exit` method exits the current domain, popping it off the domain stack. The `exit` method exits the current domain, popping it off the domain stack.
Expand All @@ -369,9 +357,6 @@ Calling `exit` changes only the active domain, and does not alter the domain
itself. `enter` and `exit` can be called an arbitrary number of times on a itself. `enter` and `exit` can be called an arbitrary number of times on a
single domain. single domain.


If the domain on which `exit` is called has been disposed, `exit` will return
without exiting the domain.

### domain.intercept(callback) ### domain.intercept(callback)


* `callback` {Function} The callback function * `callback` {Function} The callback function
Expand Down Expand Up @@ -500,7 +485,6 @@ rejections.
[`EventEmitter`]: events.html#events_class_eventemitter [`EventEmitter`]: events.html#events_class_eventemitter
[`domain.add(emitter)`]: #domain_domain_add_emitter [`domain.add(emitter)`]: #domain_domain_add_emitter
[`domain.bind(callback)`]: #domain_domain_bind_callback [`domain.bind(callback)`]: #domain_domain_bind_callback
[`domain.dispose()`]: #domain_domain_dispose
[`domain.exit()`]: #domain_domain_exit [`domain.exit()`]: #domain_domain_exit
[`setInterval()`]: timers.html#timers_setinterval_callback_delay_args [`setInterval()`]: timers.html#timers_setinterval_callback_delay_args
[`setTimeout()`]: timers.html#timers_settimeout_callback_delay_args [`setTimeout()`]: timers.html#timers_settimeout_callback_delay_args
Expand Down
48 changes: 4 additions & 44 deletions lib/domain.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -75,21 +75,12 @@ function Domain() {
} }


Domain.prototype.members = undefined; Domain.prototype.members = undefined;
Domain.prototype._disposed = undefined;




// Called by process._fatalException in case an error was thrown. // Called by process._fatalException in case an error was thrown.
Domain.prototype._errorHandler = function _errorHandler(er) { Domain.prototype._errorHandler = function _errorHandler(er) {
var caught = false; var caught = false;


// ignore errors on disposed domains.
//
// XXX This is a bit stupid. We should probably get rid of
// domain.dispose() altogether. It's almost always a terrible
// idea. --isaacs
if (this._disposed)
return true;

if (!util.isPrimitive(er)) { if (!util.isPrimitive(er)) {
er.domain = this; er.domain = this;
er.domainThrown = true; er.domainThrown = true;
Expand Down Expand Up @@ -160,8 +151,6 @@ Domain.prototype._errorHandler = function _errorHandler(er) {




Domain.prototype.enter = function() { Domain.prototype.enter = function() {
if (this._disposed) return;

// note that this might be a no-op, but we still need // note that this might be a no-op, but we still need
// to push it onto the stack so that we can pop it later. // to push it onto the stack so that we can pop it later.
exports.active = process.domain = this; exports.active = process.domain = this;
Expand All @@ -171,10 +160,9 @@ Domain.prototype.enter = function() {




Domain.prototype.exit = function() { Domain.prototype.exit = function() {
// skip disposed domains, as usual, but also don't do anything if this // don't do anything if this domain is not on the stack.
// domain is not on the stack.
var index = stack.lastIndexOf(this); var index = stack.lastIndexOf(this);
if (this._disposed || index === -1) return; if (index === -1) return;


// exit all domains until this one. // exit all domains until this one.
stack.splice(index); stack.splice(index);
Expand All @@ -187,8 +175,8 @@ Domain.prototype.exit = function() {


// note: this works for timers as well. // note: this works for timers as well.
Domain.prototype.add = function(ee) { Domain.prototype.add = function(ee) {
// If the domain is disposed or already added, then nothing left to do. // If the domain is already added, then nothing left to do.
if (this._disposed || ee.domain === this) if (ee.domain === this)
return; return;


// has a domain already - remove it first. // has a domain already - remove it first.
Expand Down Expand Up @@ -224,9 +212,6 @@ Domain.prototype.remove = function(ee) {




Domain.prototype.run = function(fn) { Domain.prototype.run = function(fn) {
if (this._disposed)
return;

var ret; var ret;


this.enter(); this.enter();
Expand All @@ -248,9 +233,6 @@ Domain.prototype.run = function(fn) {




function intercepted(_this, self, cb, fnargs) { function intercepted(_this, self, cb, fnargs) {
if (self._disposed)
return;

if (fnargs[0] && fnargs[0] instanceof Error) { if (fnargs[0] && fnargs[0] instanceof Error) {
var er = fnargs[0]; var er = fnargs[0];
util._extend(er, { util._extend(er, {
Expand Down Expand Up @@ -291,9 +273,6 @@ Domain.prototype.intercept = function(cb) {




function bound(_this, self, cb, fnargs) { function bound(_this, self, cb, fnargs) {
if (self._disposed)
return;

var ret; var ret;


self.enter(); self.enter();
Expand All @@ -318,22 +297,3 @@ Domain.prototype.bind = function(cb) {


return runBound; return runBound;
}; };


Domain.prototype.dispose = util.deprecate(function() {
if (this._disposed) return;

// if we're the active domain, then get out now.
this.exit();

// remove from parent domain, if there is one.
if (this.domain) this.domain.remove(this);

// kill the references so that they can be properly gc'ed.
this.members.length = 0;

// mark this domain as 'no longer relevant'
// so that it can't be entered or activated.
this._disposed = true;
}, 'Domain.dispose is deprecated. Recover from failed I/O actions explicitly ' +
'via error event handlers set on the domain instead.', 'DEP0012');
9 changes: 0 additions & 9 deletions lib/timers.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -250,15 +250,6 @@ function listOnTimeout() {


var domain = timer.domain; var domain = timer.domain;
if (domain) { if (domain) {

// If the timer callback throws and the
// domain or uncaughtException handler ignore the exception,
// other timers that expire on this tick should still run.
//
// https://github.com/nodejs/node-v0.x-archive/issues/2631
if (domain._disposed)
continue;

domain.enter(); domain.enter();
} }


Expand Down
1 change: 0 additions & 1 deletion src/env.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ struct performance_state;
V(dest_string, "dest") \ V(dest_string, "dest") \
V(destroy_string, "destroy") \ V(destroy_string, "destroy") \
V(detached_string, "detached") \ V(detached_string, "detached") \
V(disposed_string, "_disposed") \
V(dns_a_string, "A") \ V(dns_a_string, "A") \
V(dns_aaaa_string, "AAAA") \ V(dns_aaaa_string, "AAAA") \
V(dns_cname_string, "CNAME") \ V(dns_cname_string, "CNAME") \
Expand Down
17 changes: 4 additions & 13 deletions src/node.cc
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1159,12 +1159,10 @@ bool ShouldAbortOnUncaughtException(Isolate* isolate) {
} }




bool DomainEnter(Environment* env, Local<Object> object) { void DomainEnter(Environment* env, Local<Object> object) {
Local<Value> domain_v = object->Get(env->domain_string()); Local<Value> domain_v = object->Get(env->domain_string());
if (domain_v->IsObject()) { if (domain_v->IsObject()) {
Local<Object> domain = domain_v.As<Object>(); Local<Object> domain = domain_v.As<Object>();
if (domain->Get(env->disposed_string())->IsTrue())
return true;
Local<Value> enter_v = domain->Get(env->enter_string()); Local<Value> enter_v = domain->Get(env->enter_string());
if (enter_v->IsFunction()) { if (enter_v->IsFunction()) {
if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) { if (enter_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
Expand All @@ -1173,16 +1171,13 @@ bool DomainEnter(Environment* env, Local<Object> object) {
} }
} }
} }
return false;
} }




bool DomainExit(Environment* env, v8::Local<v8::Object> object) { void DomainExit(Environment* env, v8::Local<v8::Object> object) {
Local<Value> domain_v = object->Get(env->domain_string()); Local<Value> domain_v = object->Get(env->domain_string());
if (domain_v->IsObject()) { if (domain_v->IsObject()) {
Local<Object> domain = domain_v.As<Object>(); Local<Object> domain = domain_v.As<Object>();
if (domain->Get(env->disposed_string())->IsTrue())
return true;
Local<Value> exit_v = domain->Get(env->exit_string()); Local<Value> exit_v = domain->Get(env->exit_string());
if (exit_v->IsFunction()) { if (exit_v->IsFunction()) {
if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) { if (exit_v.As<Function>()->Call(domain, 0, nullptr).IsEmpty()) {
Expand All @@ -1191,7 +1186,6 @@ bool DomainExit(Environment* env, v8::Local<v8::Object> object) {
} }
} }
} }
return false;
} }




Expand Down Expand Up @@ -1398,9 +1392,7 @@ InternalCallbackScope::InternalCallbackScope(Environment* env,
CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());


if (env->using_domains()) { if (env->using_domains()) {
failed_ = DomainEnter(env, object_); DomainEnter(env, object_);
if (failed_)
return;
} }


if (asyncContext.async_id != 0) { if (asyncContext.async_id != 0) {
Expand Down Expand Up @@ -1432,8 +1424,7 @@ void InternalCallbackScope::Close() {
} }


if (env_->using_domains()) { if (env_->using_domains()) {
failed_ = DomainExit(env_, object_); DomainExit(env_, object_);
if (failed_) return;
} }


if (IsInnerMakeCallback()) { if (IsInnerMakeCallback()) {
Expand Down
25 changes: 0 additions & 25 deletions test/parallel/test-domain-abort-when-disposed.js

This file was deleted.

97 changes: 0 additions & 97 deletions test/parallel/test-domain-exit-dispose-again.js

This file was deleted.

Loading

0 comments on commit 602fd36

Please sign in to comment.