-
Notifications
You must be signed in to change notification settings - Fork 164
Description
Description
As the title says, simply importing @opentui/core disables all teardown hooks on Effect (or any other library, for that matter).
Example
import { Effect } from "effect";
import { BunRuntime } from "@effect/platform-bun";
// Import opentui with side-effects
import "@opentui/core";
const program = Effect.async<void, Error>((resume) => {
console.log("Running effect...");
// Complete the effect after 10s
const id = setTimeout(() => {
console.log("Effect completed normally!");
resume(Effect.void);
}, 10000);
// Return an effect to run if the fiber is interrupted
return Effect.sync(() => {
console.log("Effect was interrupted!");
clearTimeout(id);
});
});
BunRuntime.runMain(program);Expected behavior
If I press CTRL+C while this program is running, I would expect the logs to be as follows:
Running effect...
^CEffect was interrupted!
Observed behavior
If I press CTRL+C while this program is running, the log is as follows:
Running effect...
^C
Proposed fixes
I've already determined that the cause is the following code snippet:
opentui/packages/core/src/renderer.ts
Lines 132 to 138 in 53017b6
| singleton("ProcessExitSignals", () => { | |
| ;["SIGINT", "SIGTERM", "SIGQUIT", "SIGABRT"].forEach((signal) => { | |
| process.on(signal, () => { | |
| process.exit() | |
| }) | |
| }) | |
| }) |
I'm only speaking for myself here, but I was not expecting that importing @opentui/core would have these kinds of side effects, and I initially thought it was a problem with my effect code.
Here are some proposals for dealing with this issue:
- Use
process.exitCode = 0;instead ofprocess.exit().
- This does not immediately cause bun to exit, and
effectruns all teardown hooks, as expected. This is a simple fix that works foreffect, and users can still useprocess.on("beforeExit", ...)andprocess.on("exit", ...). - However, as far as I am aware, after setting
exitCode, it is impossible to stop the runtime from terminating. As such, this might still be a problem for some users who might want to ignore SIGINT and some other signals. - Furthermore, this fix still doesn't eliminate side effects when importing
@opentui/core.
- OR: do not add the event handlers for the process exit signals.
- If this is needed for some sort of cleanup, or to allow the process to be shut down when these signals are received, I would propose that a new option can be added to the
renderfunction, which would allow users to specify what to do when these signals are received. - This option could have as the default implementation
(signalType: ...) => process.exitCode = 0;.
- OR: put this singleton under an environment variable.
(I'd like to note that I'm not really familiar with the opentui codebase, and I don't know how much effort these ideas would take to implement. These are just what I thought of when writing this issue!)
Thanks!