Comments (14)
Really the immediate question that jumps to mind is why is your main process responsible for spawning the database.
That aside, you can, in theory, achieve this yourself using the sigusr2
signal capture: https://github.com/remy/nodemon?tab=readme-ov-file#controlling-shutdown-of-your-script
from nodemon.
Whether or not using SIGUSR2
works depends on the exact implementation of how specific spawned subprocess handles the signal (in fact not just the spawned subprocess, but any subprocess of that one as well), which is rarely documented, especially not for any transitive subprocesses (which might not be documented at all).
Also if the process simply does not handle the SIGUSR2
signal, then the default behavior is for it to terminate - which is exactly what I want to avoid.
Really the immediate question that jumps to mind is why is your main process responsible for spawning the database.
In my concrete case it is because the server normally connects to a real production database, but during development (which is also when I want to use nodemon) it spawns its own, correctly configured DB, so the developers don't need to set it up themselves - instead they just run the dev
script that does it for them.
The question then might also be why not to start it outside nodemon... Well, to this I have two answers:
- There would be need to communicate things like dynamically chosen port or auto-generated credentials to the process and this would need some bigger framework to do that nicely; wheres if the server is the one that manages db run, it gets these "for free"
- Sometimes it is useful to run the database only in memory, or have multiple instances with independent dbs (such as during unit testing) - doing things this way just allows reusing the code everywhere instead of having a special solution for each path
Also note, that database is only one such example. Another (for me) common one is working with puppeteer - a framework for running browsers with automation. Browsers are notorious for spawning many subprocesses and there is no documentation on how they behave when some of them receive a specific signal, in arbitrary order.
from nodemon.
You have control of the top level process, so you can hook the signal. Have you tried this, to then gracefully handle your mongo-memory-thing then exit your own process?
from nodemon.
I did - that is why I made this issue - it is not possible. My top process does hook the signal and does correctly handle it.
Problem is, that I don't have control about any child processes and the way nodemon does the signaling it signals all the children directly - so in a way that I literally can't hook without modifying the children.
Even making a wrapper around children is not a possible solution - because nodemon gets whole subtree and signals all processes in it, it will simply bypass any wrapper.
from nodemon.
Ref:
Lines 403 to 429 in f8e3b8c
The comments in the code literally say that - "we use psTree to kill the full subtree of nodemon".
What I'm looking for is having a flag that will prevent this behavior and instead only "kill" the parent - letting it do the cleanup for any potential children.
If you agree with that, I would be willing to make a PR that implements this behavior.
from nodemon.
Okay, so, the code isn't really doing what the author expects: if I trap the signal, I don't expect nodemon to signal my subprocesses.
I'm not keen on adding a flag to solve this (see design principles), but this may be the only way to solve the issue.
The problem I see is that nodemon has no way to know if the signal was trapped, or more importantly: not. Because if the signal is not trapped, then nodemon needs to kill the full process tree.
The only way I've seen (and I'm not even sure it's reliable) is to listen for the exit event on the spawned process and check the exit code matches the signal - except this only happens once the process has exited and that's a whole big problem that nodemon and contributors filing issues have been trying to get right for years.
Do you have thoughts on how it can be archived without a flag?
from nodemon.
In the optimal world it would actually be the other way around than it is currently - the behavior of nodemon should be to only kill the parent - in that case any child of that parent should request a SIGHUP
signal when its parent dies and exit by itself - the responsibility should be on the child.
The whole problem is, that some programs don't do this (it actually is moderately hard to do it correctly without any race conditions) and the current workaround might be needed in specific cases.
The current behavior basically prefers doing the "non-ideal" thing, thinking all processes will not handle this correctly.
One possible solution could be getting a subprocess tree of the main process, then killing only the main process, waiting a short timeout, and if any child is still alive then force-killing those (because by the time parent exits it should have cleaned up the children already) - no matter the signal/code the parent exited with.
There are however other problems with this approach - namely race conditions. If the parent starts a new child process between the resolution of the process tree and the kill (no matter if before or after the signal is sent/delivered), then these new processes won't be killed, because by that point there is no way to find them.
from nodemon.
I honestly think that a flag is the best solution here - what you are talking about (detecting if process does handle the signal) is in a way also a flag - it is just set by the OS (if you do manage to get it) instead of being set explicitly by the user.
I think having a flag for "I want to handle the signal myself" is better solution than changing this behavior implicitly based on this info. It also goes the most in the design direction of "Let individuals build on top of nodemon".
Also that info might be unreliable and obscure for the user - if there is a framework around the application, then the framework itself might handle the signal without the actual developer handling it - so the resulting behavior would be unexpected for the developer...
And there definitely isn't a way to know if it was the developer who got to handle the signal or if it was some framework.
What I mean is: Node.js for example by itself always handles the signal - it is just matter that if there is no JS callback for it, then it proceeds to shut down by itself. From the view of the OS it still however is a handled signal not resulting in directly killed process.
from nodemon.
Yet another possible solution would be going closer to the containerization frameworks (e.g. how Docker is able to reliably stop the whole container no matter what processes and when are started inside it).
On linux this could be achieved by becoming a child subreaper (see prctl(2), PR_SET_CHILD_SUBREAPER
) - which would cause any orphaned children to be re-parented to this process, so it could then collect them and "reap" them when desired (instead of the orphans being re-parented to 1
/init
and being undiscoverable after that by nodemon).
While this solution would solve this issue, it is very platform dependent (I don't have nearly enough Windows knowledge to say how one could approach this there) and it would almost definitely require having a native binary to do this.
Yet another possible solution would be to literally use a container to run the development server(s) and their children - it is a technology that already exists and is very well tested. I however think, that that goes way past of what Nodemon is intended to do...
from nodemon.
This issue has been automatically marked as idle and stale because it hasn't had any recent activity. It will be automtically closed if no further activity occurs. If you think this is wrong, or the problem still persists, just pop a reply in the comments and @remy will (try!) to follow up.
Thank you for contributing <3
from nodemon.
[not stale]
Hi @remy! Based on my above answers, do you agree that the simplest course of action that does solve the issue is adding a new flag? Would you accept PRs implementing this?
from nodemon.
from nodemon.
This issue has been automatically marked as idle and stale because it hasn't had any recent activity. It will be automtically closed if no further activity occurs. If you think this is wrong, or the problem still persists, just pop a reply in the comments and @remy will (try!) to follow up.
Thank you for contributing <3
from nodemon.
Automatically closing this issue due to lack of activity
from nodemon.
Related Issues (20)
- Force a full restart? HOT 7
- is there a way to delay before re-spawn / re-execution? otherwise CPU goes to 100% HOT 1
- Restart event calls start event as well when files change HOT 3
- Passing an array into ext config HOT 5
- nodemon is not restarting server automatically HOT 1
- Restart not firing beyond deletion of directory under watch, when this directory structure is recreated (on Ubuntu 22.04) HOT 12
- Nodemon ignores `--ext` argument HOT 3
- not working with Node.js version 20.12.x HOT 12
- Unable to enable logs when using nodemon as a module HOT 5
- Document differences and/or provide migration guide to Node.js native watch mode HOT 1
- Restart app on specific exit code HOT 3
- Input input cyrillic char's in python input work not well HOT 2
- Nodemon Internal watch failed HOT 2
- nodemon does not restart the server ([nodemon] restarting due to changes...) HOT 2
- Question not a bug - How to restart app on crash HOT 2
- [CVE-2024-4068] Uncontrolled resource consumption found in braces (non-issue, see comments) HOT 3
- bash node env vars for readline HOT 2
- Problem with Newley released types HOT 22
- config.env should be overridden by runtime env variables
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nodemon.