Skip to content

Commit 41a8c2f

Browse files
ddinuRomainMuller
authored andcommitted
fix(kernel): stack overflow in KernelHost.run() (#780)
Fixes #778. This PR eliminates the mutual recursion between `KernelHost.run()` and `KernelHost.processRequest()` by scheduling the recursive `KernelHost.run()` call to run on the next iteration of the event loop. The code change has been tested as follows: - by running the stress-test script with and without the change to confirm that the crash occurs without the change and does not occur with the change; - by running the unit tests to confirm that behavior is consistent; - by synthesizing our internal CDK stack and confirming that the crash does not occur and that resources are generated correctly.
1 parent 7b3b059 commit 41a8c2f

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

packages/jsii-runtime/lib/host.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ export class KernelHost {
1414
return; // done
1515
}
1616

17-
this.processRequest(req, () => this.run());
17+
this.processRequest(req, () => {
18+
// Schedule the call to run on the next event loop iteration to
19+
// avoid recursion.
20+
setImmediate(() => this.run())
21+
});
1822
}
1923

2024
private callbackHandler(callback: api.Callback) {

packages/jsii-runtime/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"scripts": {
1111
"build": "tsc --build && chmod +x bin/jsii-runtime && /bin/bash ./bundle.sh",
1212
"watch": "tsc --build -w",
13-
"test": "/bin/bash test/playback-test.sh",
13+
"test": "/bin/bash test/playback-test.sh && node test/stress-test.js",
1414
"package": "package-js"
1515
},
1616
"devDependencies": {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { InputOutput, Input, Output } from "../lib/in-out";
2+
import { KernelHost } from "../lib/host";
3+
4+
const requestCount = 250000;
5+
6+
class FakeInputOutput extends InputOutput {
7+
debug = false;
8+
private count: number = 0;
9+
10+
write(_: Output) { }
11+
12+
read(): Input | undefined {
13+
if(this.count == requestCount) {
14+
return undefined;
15+
}
16+
17+
++this.count;
18+
return { api: 'stats' };
19+
}
20+
}
21+
22+
const inout = new FakeInputOutput();
23+
const host = new KernelHost(inout, { debug: false, noStack: false });
24+
host.run();
25+
26+
console.info("jsii-runtime stress test succeeded");

0 commit comments

Comments
 (0)