events: move domain handling from events to domain
PR-URL: https://github.com/nodejs/node/pull/17403 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
This commit is contained in:
parent
a803bcaab8
commit
cf4448cbd4
@ -31,11 +31,6 @@ const EventEmitter = require('events');
|
|||||||
const errors = require('internal/errors');
|
const errors = require('internal/errors');
|
||||||
const { createHook } = require('async_hooks');
|
const { createHook } = require('async_hooks');
|
||||||
|
|
||||||
// communicate with events module, but don't require that
|
|
||||||
// module to have to load this one, since this module has
|
|
||||||
// a few side effects.
|
|
||||||
EventEmitter.usingDomains = true;
|
|
||||||
|
|
||||||
// overwrite process.domain with a getter/setter that will allow for more
|
// overwrite process.domain with a getter/setter that will allow for more
|
||||||
// effective optimizations
|
// effective optimizations
|
||||||
var _domain = [null];
|
var _domain = [null];
|
||||||
@ -387,3 +382,49 @@ Domain.prototype.bind = function(cb) {
|
|||||||
|
|
||||||
return runBound;
|
return runBound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Override EventEmitter methods to make it domain-aware.
|
||||||
|
EventEmitter.usingDomains = true;
|
||||||
|
|
||||||
|
const eventInit = EventEmitter.init;
|
||||||
|
EventEmitter.init = function() {
|
||||||
|
this.domain = null;
|
||||||
|
if (exports.active && !(this instanceof exports.Domain)) {
|
||||||
|
this.domain = exports.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventInit.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
const eventEmit = EventEmitter.prototype.emit;
|
||||||
|
EventEmitter.prototype.emit = function emit(...args) {
|
||||||
|
const domain = this.domain;
|
||||||
|
if (domain === null || domain === undefined || this === process) {
|
||||||
|
return eventEmit.apply(this, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const type = args[0];
|
||||||
|
// edge case: if there is a domain and an existing non error object is given,
|
||||||
|
// it should not be errorized
|
||||||
|
// see test/parallel/test-event-emitter-no-error-provided-to-error-event.js
|
||||||
|
if (type === 'error' && args.length > 1 && args[1] &&
|
||||||
|
!(args[1] instanceof Error)) {
|
||||||
|
domain.emit('error', args[1]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
domain.enter();
|
||||||
|
try {
|
||||||
|
return eventEmit.apply(this, args);
|
||||||
|
} catch (er) {
|
||||||
|
if (typeof er === 'object' && er !== null) {
|
||||||
|
er.domainEmitter = this;
|
||||||
|
er.domain = domain;
|
||||||
|
er.domainThrown = false;
|
||||||
|
}
|
||||||
|
domain.emit('error', er);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
domain.exit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var domain;
|
|
||||||
var spliceOne;
|
var spliceOne;
|
||||||
|
|
||||||
function EventEmitter() {
|
function EventEmitter() {
|
||||||
@ -32,9 +31,6 @@ module.exports = EventEmitter;
|
|||||||
// Backwards-compat with node 0.10.x
|
// Backwards-compat with node 0.10.x
|
||||||
EventEmitter.EventEmitter = EventEmitter;
|
EventEmitter.EventEmitter = EventEmitter;
|
||||||
|
|
||||||
EventEmitter.usingDomains = false;
|
|
||||||
|
|
||||||
EventEmitter.prototype.domain = undefined;
|
|
||||||
EventEmitter.prototype._events = undefined;
|
EventEmitter.prototype._events = undefined;
|
||||||
EventEmitter.prototype._maxListeners = undefined;
|
EventEmitter.prototype._maxListeners = undefined;
|
||||||
|
|
||||||
@ -66,14 +62,6 @@ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EventEmitter.init = function() {
|
EventEmitter.init = function() {
|
||||||
this.domain = null;
|
|
||||||
if (EventEmitter.usingDomains) {
|
|
||||||
// if there is an active domain, then attach to it.
|
|
||||||
domain = domain || require('domain');
|
|
||||||
if (domain.active && !(this instanceof domain.Domain)) {
|
|
||||||
this.domain = domain.active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._events === undefined ||
|
if (this._events === undefined ||
|
||||||
this._events === Object.getPrototypeOf(this)._events) {
|
this._events === Object.getPrototypeOf(this)._events) {
|
||||||
@ -114,47 +102,26 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
|
|||||||
else if (!doError)
|
else if (!doError)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const domain = this.domain;
|
|
||||||
|
|
||||||
// If there is no 'error' event listener then throw.
|
// If there is no 'error' event listener then throw.
|
||||||
if (doError) {
|
if (doError) {
|
||||||
let er;
|
let er;
|
||||||
if (args.length > 0)
|
if (args.length > 0)
|
||||||
er = args[0];
|
er = args[0];
|
||||||
if (domain !== null && domain !== undefined) {
|
if (er instanceof Error) {
|
||||||
if (!er) {
|
|
||||||
const errors = lazyErrors();
|
|
||||||
er = new errors.Error('ERR_UNHANDLED_ERROR');
|
|
||||||
}
|
|
||||||
if (typeof er === 'object' && er !== null) {
|
|
||||||
er.domainEmitter = this;
|
|
||||||
er.domain = domain;
|
|
||||||
er.domainThrown = false;
|
|
||||||
}
|
|
||||||
domain.emit('error', er);
|
|
||||||
} else if (er instanceof Error) {
|
|
||||||
throw er; // Unhandled 'error' event
|
throw er; // Unhandled 'error' event
|
||||||
} else {
|
}
|
||||||
// At least give some kind of context to the user
|
// At least give some kind of context to the user
|
||||||
const errors = lazyErrors();
|
const errors = lazyErrors();
|
||||||
const err = new errors.Error('ERR_UNHANDLED_ERROR', er);
|
const err = new errors.Error('ERR_UNHANDLED_ERROR', er);
|
||||||
err.context = er;
|
err.context = er;
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handler = events[type];
|
const handler = events[type];
|
||||||
|
|
||||||
if (handler === undefined)
|
if (handler === undefined)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
let needDomainExit = false;
|
|
||||||
if (domain !== null && domain !== undefined && this !== process) {
|
|
||||||
domain.enter();
|
|
||||||
needDomainExit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof handler === 'function') {
|
if (typeof handler === 'function') {
|
||||||
handler.apply(this, args);
|
handler.apply(this, args);
|
||||||
} else {
|
} else {
|
||||||
@ -164,9 +131,6 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
|
|||||||
listeners[i].apply(this, args);
|
listeners[i].apply(this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needDomainExit)
|
|
||||||
domain.exit();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user