JSii blocks the node process when the JS code is not being called by the host
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 267
- Avg merge
- 1d 25m
- Merged PRs (30d)
- 14
Description
### Describe the bug
In (at least) Java, the node process is blocked while it is waiting for new method calls.
Specifically, promises that are running in the JSii-ed node process don't run at all when the host process has no active calls to the JSii-ed process.
I have a small repro of this bug in [this repository](https://github.com/TimothyJones/jsii-async-issue). Here's a breakdown of what's in that repo:
* There is a [JS class](https://github.com/TimothyJones/jsii-async-issue/blob/main/jsii-module/src/index.ts#LL7C3-L7C3) that kicks off a "tick" promise chain which [logs to console every quarter second](https://github.com/TimothyJones/jsii-async-issue/blob/main/jsii-module/src/index.ts#L1), and will print these logs even after `longRunningSomething()` has completed.
*The console logs have a number in them that tell you which call of `longRunningSomething()` those logs were kicked off by.
* When called from JS, this tick prints every quarter second (as expected) - this isn't in the repo, but is easy to demonstrate with:
```
new Example().longRunningSomething();
console.log("Long running something complete")
await new Promise((resolve) => setTimeout(resolve, 5000)); // logs will keep printing while waiting for this to complete
```
* When [called from Java](https://github.com/TimothyJones/jsii-async-issue/blob/main/java-host/untitled/src/main/java/org/example/Main.java#L11), the ticks only and print when the execution is with node.
* When node returns to Java, the ticks stop.
* The ticks restart again [if further calls to JS are made](https://github.com/TimothyJones/jsii-async-issue/blob/main/java-host/untitled/src/main/java/org/example/Main.java#L15).
Although this is an `async` example, the blocking of the node process happens regardless of whether or not the call in to it is async. I only made an async example so that I could make `longRunningSomething()` take a while so you can see that the ticks run while node is doing something that it is planning to return to java.
### Expected Behavior
When the java code at that link is run, I expect the `(1)` ticks to continue after the call to `longRunningSomething()` while the Java thread is doing something else.
### Current Behavior
When the java code at that link is run, the `(1)` ticks stop once the JS returns to Java.
The `(1)` ticks restart when
### Reproduction Steps
With JDK 20.0.1 (this is just the version I know works, others probably do too):
```
git clone git@github.com:TimothyJones/jsii-async-issue.git
cd java-host/untitled
./gradlew run
```
Observe that the ticks stop printing when Java is waiting
### Possible Solution
My guess is that the stdin/out protocol for communicating between JSii and the host uses blocking calls on the JS side. I suspect that non-blocking calls would solve this problem, and possibly several others.
Because JSii communicates across a stdin/out protocol with another process, I think there's quite a bit of flexibility in the way that async is treated - one side could see it as async, while the other sees it as sync (and vice versa).
### Additional Information/Context
This is related to [this issue](https://github.com/aws/jsii/issues/3016) in that I think this is the cause, rather than aync hairiness.
(that issue describes the exact situation that I have in my real code, though)
This is a blocking issue for me, I would be happy to look in to it (but definitely would need some guidance on where to look)
### SDK version used
jsii@5.1.1
### Environment details (OS name and version, etc.)
node 18.13.0, JVM 20.0.1, MacOS 13.3.1 (a)
Contributor guide
Research direction
Run ./gradlew run from java-host/untitled in the linked reproduction, then inspect jsii-module/src/index.ts and java-host/untitled/src/main/java/org/example/Main.java. Trace the stdin/stdout behavior while Java is idle; done means the tick logs continue after longRunningSomething() returns instead of waiting for another JS call.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, node.js, typescript
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100