-
-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emulator shutdowns are not "clean" when using executors #40
Comments
Hi @WhatsThatItsPat, What is your current workaround on this? |
I've just been running the I've also added this to my "scripts": {
...
"kill-all": "npx kill-port 4000 5000 5001 8080 8085 9099 9199"
}, |
Every time I terminate the emulator from
"emulate": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "concurrently --raw \"firebase emulators:start --config firebase.json --only firestore,auth,storage,functions --import=emulator --export-on-exit=emulator\""
}
}, |
I'm working under windows 10 with node v16.15.1. The nx cli have some weird design to exit itself immediately under SIGINT. Here is my nx patch up file if anyone need its. Its solve my problem and making everything working great, but I don't know if it will cause other problem D: I may need find time to to fire issue about this to nx repo.
diff --git a/node_modules/nx/src/tasks-runner/forked-process-task-runner.js b/node_modules/nx/src/tasks-runner/forked-process-task-runner.js
index 5cbc819..eb42bff 100644
--- a/node_modules/nx/src/tasks-runner/forked-process-task-runner.js
+++ b/node_modules/nx/src/tasks-runner/forked-process-task-runner.js
@@ -226,21 +226,21 @@ class ForkedProcessTaskRunner {
setupOnProcessExitListener() {
process.on('SIGINT', () => {
this.processes.forEach((p) => {
- p.kill('SIGTERM');
+ // p.kill('SIGTERM');
});
// we exit here because we don't need to write anything to cache.
- process.exit();
+ // process.exit();
});
process.on('SIGTERM', () => {
this.processes.forEach((p) => {
- p.kill('SIGTERM');
+ // p.kill('SIGTERM');
});
// no exit here because we expect child processes to terminate which
// will store results to the cache and will terminate this process
});
process.on('SIGHUP', () => {
this.processes.forEach((p) => {
- p.kill('SIGTERM');
+ // p.kill('SIGTERM');
});
// no exit here because we expect child processes to terminate which
// will store results to the cache and will terminate this process
diff --git a/node_modules/@nrwl/workspace/src/executors/run-commands/run-commands.impl.js b/node_modules/@nrwl/workspace/src/executors/run-commands/run-commands.impl.js
index 77fa9c9..7e7d380 100644
--- a/node_modules/@nrwl/workspace/src/executors/run-commands/run-commands.impl.js
+++ b/node_modules/@nrwl/workspace/src/executors/run-commands/run-commands.impl.js
@@ -35,6 +35,7 @@ const propKeys = [
'outputPath',
];
function default_1(options, context) {
+ ['exit','SIGTERM','SIGINT','SIGHUP'].forEach(signal=>process.once(signal, ()=>{}));
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield loadEnvVars(options.envFile);
const normalized = normalizeOptions(options);
@@ -120,9 +121,11 @@ function createProcess(command, readyWhen, color, cwd) {
/**
* Ensure the child process is killed when the parent exits
*/
- const processExitListener = () => childProcess.kill();
- process.on('exit', processExitListener);
- process.on('SIGTERM', processExitListener);
+ // const processExitListener = () => childProcess.kill();
+ // process.on('exit', processExitListener);
+ // process.on('SIGTERM', processExitListener);
+ // process.on('SIGINT', processExitListener);
+ // process.on('SIGHUP', processExitListener);
childProcess.stdout.on('data', (data) => {
process.stdout.write(data);
if (readyWhen && data.toString().indexOf(readyWhen) > -1) {
|
There's a fair bit of chat in the Nx repo about Nx task runner not terminating processes cleanly, and we have limited control over that. The solution from @WhatsThatItsPat above works well so I've incorporated that into the latest plugin generator for the
It's not ideal because the cleanup only happens before starting the emulator, not when the task is ended, but its better than nothing. Frankly, there's a lot of Nx edge cases that we can but hope get resolved one day. |
Looks like there might be a fix from Nx for this released soon: nrwl/nx#13885 |
There's a further negative side effect of this Nx behaviour, which is that using |
FWIW I've decided to work around this by using an npm script for serving:
This handles the sigint properly because we're calling firebase CLI outside of the Nx run-command wrapper. (arguably the kill-port part is redundant if the emulator shuts down properly!) |
Another possible fix would be to have a custom 'serve' executor in the nx-firebase plugin that runs the necessary firebase command but also handles the sigint similarly to the patch above |
I felt they are trying so hard to dealing signal problem cross platform and still unable to deal its for all situation gracefully(signal propagating seems like a common problem with these cli tools(ex. concurrently from npm,melos from flutter)), as far as I known if the emulator didn't shutdown gracefully,the auto export won't work. Making a specified executor for firebase emulator seems like a good idea,because we don't need to consider other situation from other program. |
Unfortunately even though that PR is now in Nx 16.1.1 it does not solve our issue - spawning the emulator from |
Understand that it still an nx issue that is blocking this issue. To add a further temporary fix in your package I suggest that a export helper script is also added to the project. That way you can manual run the scipt before shutdown to export your data. This will mean that kill ports and export will at a minimum simulate a clean exit until they fix the problem. |
Bit of research on this problem I think that firebase-tools is not handling a Here is the area of the code of NX that sends the signal to the sub-processes: This means there is no clean shutdown, which includes exports and killing ports. This is mentioned as a feature request in the firebase-tools repo to handle this feature firebase/firebase-tools#3578 They have added it to a roadmap but with no timeline. It also meantioned in this issue on nx: nrwl/nx#18255 So this issue could be fixed by either package. |
I was giving this some more thought. I'm thinking it might be possible to implement a custom executor in the plugin that calls the CLI directly and handles SIGTERM etc properly. Since run-command wont be involved, it might just work.... 🤔 |
@Bullfrog1234 Thanks to your post above I think I've isolated the issue with Nx. If we simply comment out |
BTW I made a start on a custom I'm wondering if a patch could be provided with the plugin somehow. |
I would welcome any feedback on the above PR. Will probably add it to next release. |
version 2.1.1 now supports clean shutdown of the emulator. 🙌 |
Thanks @simondotm sorry didn't get to review. Been off the grid for a while now. It looks amazing thanks for the amazing work. |
I spent the whole day looking at my executor why it just kills the process immediately, without waiting for SIGINT handler. And then I realize that NX internally is doing process.exit() on SIGINT. I'm wondering why is this so? |
For some reason,seems like cli tools have common issue with process signal. Most of them just kill process or sending double SIGINT for no reason,I wondering why too. |
After using
firebase emulators:start
in the terminal and enteringctrl-c
to end the process, I get lengthy output telling me about the shutdown process:But after running
nx serve functions
ornx emulate functions
, ending the process withctrl-c
doesn't show any of the output and I don't think everything is being shut down properly.When I restart the emulators I get warnings about "multiple instances" or specific ports that are still in use:
Additionally, when I try to import & export emulator data, the data isn't exported to the correct place and extra
firebase-export-{something}
directories are created.I've adjusted the command in the emulate executor to look like this:
When I run this directly in the terminal, everything shuts down fine and works as expected.
I'm on macOS, my firebase tools version is 9.16.6, and node is 16.8.0.
The text was updated successfully, but these errors were encountered: