Skip to content

Commit 5668628

Browse files
authored
chore(docs): document interrupt handling (#1050)
1 parent 432988b commit 5668628

5 files changed

+136
-2
lines changed

docs/cli-interrupt-events.png

235 KB
Loading

docs/cli-interrupt-handling.png

146 KB
Loading

docs/diagrams.drawio

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<mxfile host="Electron" modified="2021-07-20T09:31:16.378Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="m0ryZ81Uoev6-Ma22SGn" version="14.6.13" type="device"><diagram id="Ff37bpA9ezkQJEPIHSPT" name="CLI REPL Evaluation">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</diagram></mxfile>
1+
<mxfile host="Electron" modified="2021-07-30T13:11:41.787Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="Dp-a2XkO5CoetIIN4JKw" version="14.6.13" type="device" pages="2"><diagram id="Ff37bpA9ezkQJEPIHSPT" name="CLI REPL Evaluation">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</diagram><diagram name="CLI Interrupt Handling" id="2WGkPQ_URlOngVTHQ9XK">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</diagram></mxfile>

docs/index.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ This folder contains development-specific documentation on the inner workings of
77
## Topics
88
Go to any of the linked topics for details:
99

10-
* [CLI REPL Code Evaluation](./cli-code-evaluation.md)
10+
* [CLI REPL Code Evaluation](./cli-code-evaluation.md)
11+
* [Interrupting Async Execution](./interrupting-async-execution.md)

docs/interrupting-async-execution.md

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Interrupting Async Execution
2+
3+
This document describes how we handle interrupting asynchronous execution of user input
4+
when the user hits `CTRL-C`.
5+
6+
## Background
7+
The Node.js REPL only handles interrupting synchronous code execution. Once the execution
8+
becomes asynchronous however, e.g. when using promises or timeouts, the standard interrupt
9+
handling does not work anymore.
10+
11+
The following is an example of synchronous code:
12+
```javascript
13+
while(true) {}
14+
```
15+
Hitting `CTRL-C` while the infinite loop is running will immediately terminate execution.
16+
17+
Taking a look at an example of asynchronous code using the Shell API:
18+
```javascript
19+
for (let i = 0; i < 10; i++) {
20+
db.coll.insert({ num: i });
21+
}
22+
```
23+
This would basically be transformed by the `async-rewriter` to something similar to:
24+
```javascript
25+
(async() => {
26+
for (let i = 0; i < 10; i++) {
27+
await db.coll.insert({ num: i });
28+
}
29+
});
30+
```
31+
As such, once the first insertion of a new document would take place, the code execution becomes
32+
asynchronous. Hitting `CTRL-C` in the Node.js REPL would then not stop the code from running.
33+
34+
## Problems to keep in mind
35+
There are a couple of things we need to keep in mind when interrupting user code execution:
36+
37+
1. To force termination of any running operations on the server side, the connections opened
38+
by the driver have to be closed. This however only works for MongoDB >4.2.
39+
2. User code may contain `try-catch-finally` blocks so we need to make sure that the error thrown
40+
when terminating a connection is not just caught and execution silently continues.
41+
3. We need to take care of code that does not use the driver, e.g. `while (true) { print('hey'); sleep(500); }`.
42+
The goal is to also immediately interrupt this code and make sure it does not continue in the background.
43+
44+
## Enforcing Interruption
45+
Before diving into how we enforce interruption of asynchronous code, we recommend reading the topic
46+
on [CLI code evaluation](./cli-code-evaluation.md) to get a rough understanding of control flow.
47+
48+
The following image contains the main aspects of code evaluation control flow but is augmented with
49+
additional information on the interrupt handling.
50+
51+
![](./cli-interrupt-events.png)
52+
53+
### Code Evaluation
54+
As you see in the image, the original `REPLServer.eval` evaluation will finish with an exception as triggered
55+
by the _Interruptor_ described below.
56+
This exception is caught inside `MongoshNodeRepl.eval` which will detect the interrupt. As such, this method
57+
will just return an "empty" result to return this call chain. It will also emit the `mongosh:eval-interrupted`
58+
event.
59+
Note that at this point, printing the prompt is explicitly suppressed.
60+
61+
To ensure that user code is indeed interrupted while asynchronous code is being executed, we leverage TypeScript
62+
decorators to wrap every Shell API function.
63+
64+
The pseudo-code wrapping to include interrupt support for the `Collection.find` API function would be similar to:
65+
```javascript
66+
const interruptPromise = interruptor.checkInterrupt(); // will throw immediately if CTRL-C already happened
67+
// otherwise the contained promise is rejected on CTRL-C
68+
69+
try {
70+
return result = Promise.race([
71+
interruptPromise.promise(), // this is never resolved but only rejected on CTRL-C!
72+
Collection.find(args) // here we call the original function
73+
]);
74+
} catch {
75+
... // throw an appropriate error (see below for exception handling details)
76+
} finally {
77+
interruptPromise.destroy(); // we make sure to de-register ourselves to not leak memory
78+
}
79+
```
80+
81+
By having this race of promises, we ensure that code calling API functions will always fail immediately when
82+
the interruptor is triggered. This will solve problem 3 outlined above.
83+
84+
### `SIGINT` handling
85+
`MongoshNodeRepl.onAsyncSigint` is registered as a `SIGINT` listener while code is being executed.
86+
The `SIGINT` listener will be called _first_ as seen in the image above by number _11_.
87+
88+
The control flow of the listener is outlined in the following image.
89+
90+
![](./cli-interrupt-handling.png)
91+
92+
Force-closing all `MongoClient` instances as seen in the image will cause operations running on the server
93+
to be immediately terminated and thus solve problem 1 outlined above.
94+
95+
### Uncatchable Errors
96+
One of the aforementioned problems is that user code might include `try-catch` blocks which could interfere
97+
with errors thrown by our interrupt handling code, explicitly the error thrown by the `interruptPromise`
98+
which is an instance of [`MongoshInterruptedError`](../packages/shell-api/src/interruptor.ts).
99+
100+
In order to prevent user code from catching the _Interrupted Error_ we make use of the `async-rewriter`.
101+
The `async-rewriter` will rewrite any `try-catch` blocks it finds to make sure a `MongoshInterruptedError`
102+
is immediately re-thrown (see [`uncatchable-exceptions.ts`](../packages/async-rewriter2/src/stages/uncatchable-exceptions.ts)).
103+
104+
For example let us look at the following user code:
105+
```javascript
106+
try {
107+
return await db.coll.count();
108+
} catch (e) {
109+
return -1;
110+
} finally {
111+
print('completed');
112+
}
113+
```
114+
115+
This code would be translated (roughly) to the following:
116+
```javascript
117+
let isCatchable;
118+
try {
119+
return await db.coll.count();
120+
} catch (e) {
121+
isCatchable = isCatchableError(e); // basically make sure e != MongoshInterruptedError
122+
if (!isCatchable) { // we immediately re-throw our uncatchable error
123+
throw e;
124+
}
125+
return -1;
126+
} finally {
127+
if (isCatchable) { // make sure the user's finalizer only runs if the error was catchable
128+
print('completed');
129+
}
130+
}
131+
```
132+
133+
This approach makes sure that problem 2 from above is properly dealt with.

0 commit comments

Comments
 (0)