Skip to content

Commit e9ac484

Browse files
committed
domain analyse
1 parent aa305e3 commit e9ac484

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

Diff for: chapter13/chapter13-2.md

+75
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,82 @@ function Domain() {
6262
}
6363
```
6464

65+
另外, domain 为了支持深层次的嵌套, 提供了 `Domain#enter``Domain#exit` 的 API。
66+
先来看 `enter`的实现,
67+
```js
68+
Domain.prototype.enter = function() {
69+
if (this._disposed) return;
70+
71+
// note that this might be a no-op, but we still need
72+
// to push it onto the stack so that we can pop it later.
73+
exports.active = process.domain = this;
74+
stack.push(this);
75+
_domain_flag[0] = stack.length;
76+
};
77+
```
78+
设置当前活跃的 `domain`, 并且为了便于回溯,将当前的 `domain` 加入到队列的后面,更新栈的深度。
79+
80+
再看 `exit`实现,
81+
```js
82+
Domain.prototype.exit = function() {
83+
// skip disposed domains, as usual, but also don't do anything if this
84+
// domain is not on the stack.
85+
var index = stack.lastIndexOf(this);
86+
if (this._disposed || index === -1) return;
87+
88+
// exit all domains until this one.
89+
stack.splice(index);
90+
_domain_flag[0] = stack.length;
91+
92+
exports.active = stack[stack.length - 1];
93+
process.domain = exports.active;
94+
};
95+
```
96+
相反的, 退出当前的 `domain`, 更新长度,设置当前活跃的 `domain`
97+
98+
读者可能好奇,我并没有显式地调用 `enter`, `exit`, 而只是简单的创建了一个 domain, 怎么会达到这种效果?
99+
100+
读者可以看看 `AsyncWrap::MakeCallback()`, 每次C++ --> JS, 都会检查 domain, 如果使用,则会显式地调用他们。
101+
其他地方读者可以自行寻找。
102+
103+
为了解决不在当前作用域的异常处理, Domain 也提供 `Domain#add``Domain#remove` 来增加 `emitter` 或者
104+
`Timer`
105+
106+
107+
回到事件的根本, 什么时候触发domain的error事件?
108+
```js
109+
process._fatalException = function(er) {
110+
var caught;
111+
112+
if (process.domain && process.domain._errorHandler)
113+
caught = process.domain._errorHandler(er) || caught;
114+
115+
if (!caught)
116+
caught = process.emit('uncaughtException', er);
117+
118+
// If someone handled it, then great. otherwise, die in C++ land
119+
// since that means that we'll exit the process, emit the 'exit' event
120+
if (!caught) {
121+
try {
122+
if (!process._exiting) {
123+
process._exiting = true;
124+
process.emit('exit', 1);
125+
}
126+
} catch (er) {
127+
// nothing to be done about it at this point.
128+
}
129+
130+
// if we handled an error, then make sure any ticks get processed
131+
} else {
132+
NativeModule.require('timers').setImmediate(process._tickCallback);
133+
}
134+
135+
return caught;
136+
};
137+
```
65138

139+
如果当前 process 使用了 domain, 也是就 `process.domain` 不为空,就调用 `_errorHandler` 来处理,
140+
当前也存在没有处理的情况,职责链来到 process, process 则触发 `uncaughtException` 事件。
66141

67142

68143
### 总结

0 commit comments

Comments
 (0)