nodeJS file — main.js
Have a website with button which can call function from main.js. I not know how restart nodeJS script correctly. Now I run process.exit() in main.js and then, with nodemon trying restart application but nodemon tell me “[nodemon] clean exit - waiting for changes before restart”. So how correctly restart application?
Clean exit means exit code 0, which means, "Everything is okay! I intended to exit." Usually, programs that exit normally don't specifically intend to be restarted. nodemon is choosing to consider that the end of the program's operation, which isn't a totally insane thing. However, nodemon being a process manager for daemons, probably ought to just restart it anyway. I would suggest using PM2 instead, it is what most people use in production and it will correctly restart the process since its whole job is to keep services running.
Aside from all of that, I want to note that allowing a browser to restart your app is probably not a good idea. If you have carefully designed your app to be stateless and handle random shutdowns and it is clustered, etc. then maybe it is fine. But generally I would not recommend it. At the very least, make sure the request is authenticated and authorized.
Related
Before I give some background, I'd like to clarify that I'm not looking for how to simply spawn a new script under the Electron runtime as a renderer process, I'm trying to use a plain Node runtime.
So I'm aware Electron has some different flavor of a JS runtime under its hood similar to NW.js and I'm trying to get consistent performant results for my report.
Unfortunately, this seems to be much more difficult than I had imagined. I'm specifically testing the speed of the mailparser module although that's not necessarily important here.
I first ran it on the Electron app we're working with, which uses Electron Forge. I called the test script through IPC as that's what we intend to use, so it was called within the callback for ipcMain.handle. Here, the performance was really bad and it was taking 30-50 seconds for our test to complete.
I then ran a test script that just opens a blank HTML file in the same Electron Forge app, and runs the test script in the background. This was much better at 8-12 seconds.
Next, I set up a new directory with a test set, a plain Electron installation, and a mailparser installation. I did not electron-rebuild here, but mailparser does rely on node-iconv and so has native bindings.
I ran a test script with Electron just calling the same line of code. This did not use Electron Forge. The performance here was slightly better at 5-9 seconds.
I then ran another test script, this time just with plain old node, and the performance here was excellent at 1-3s.
So I have two questions here:
Why is the performance varying so much in the Electron tests? Although I used IPCMain, I used the new .handle which should be asynchronous and run in the context of Electron's node runtime, so it should have the same performance as running outside the callback. Moreover, the Electron Forge and plain Electron tests also differ by a couple of seconds which made no sense to me as I assumed Electron Forge would just wrap the Electron binary under the hood.
Seeking optimal and consistent results, I'm wondering how I can spin up a child process with the node runtime inside Electron. Doing this normally just starts a new renderer process which is running Electron's (slower) JS runtime. I'd like to avoid leaving Electron Forge but the only solution I can think of is to bundle precompiled binaries with the process running under the Node runtime built for each platform.
For question 1 it’s hard to know what the problem is without being able to replicate it in code. You might try posting an issue on the Github site for the Electron team re this. They are more likely to know the answer, but they ask for code as well.
Having said that, it isn’t that hard to spin up a child process that is just running node and frees you from Electron/Electron Forge overhead. The easiest is to use node’s fork command, but to tell it to use the main node executable rather than electron.exe. You can just hand it a script to run, so you don’t need to worry about precompiled binaries.
The code below (and here) running on the main process will run a script called server.js in the same folder:
const serverPath = path.join(__dirname, 'server.js');
const { fork } = require('child_process');
child = fork(serverPath, [],
{
execPath: "node",
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
});
If you do that you get a child node.exe process with IPC enabled, rather than an electron.exe process. It can be made to communicate over IPC with the main Electron process. It can also use any npm modules installed from your usual package.json, because the script can be in the same folder as your other scripts. So if it works this is quite a clean solution.
I entertained myself this afternoon by writing some code that does this. I’ve put this on Github. It uses mailparser to parse a simple mail in the node.exe process in server.js.
This also packages correctly with Electron Forge as far as I can see, in terms of including the correct scripts. It won't package node itself, so that either needs to be installed on the target machine or I think you'll need to distribute node.exe.
By the way it isn’t entirely clear whether you’ve actually tried this approach and it’s one of those scenarios where it runs slowly. There is still some overhead, because we’re setting up IPC. If it does still run slowly in your use case then I think it’s possible to use node’s spawn command to create a completely standalone process.
I have this program where a server is made. Before the server can start though I need to register it. This is a one time thing as re-registering it will change all the dcom data and settings to factory settings. Which I don't want. So What I have set up is a JS file that runs my program and gives it a parameter argument "register" which is handled in my program to register the server. Similarly before uninstalling I want to run a similar JS file that passes an unregister argument so the server is no longer listed on client views after it's been removed. To be clear I have both of these JS files working fine and they successfully register/unregister my server as needed.
My issue is that I've added these files in the application directory and in my Visual studio installer: Setup Project, I have gone to right click installer project > view > custom actions. Then I right clicked the install folder and added my regserver.JS file and similarly for uninstall I've added my unregserver.JS file. The problem lays in the order that these get run. When the intaller runs it first run my regserver.JS. This is bad because there is no .exe of my program existing yet so an error is thrown... Is there a way to specify in my project that this JS is only to be executed AFTER the installation finishes?
Or is there a clever wrap around to this? Maybe I'm doing it all wrong!
EDIT: ..just an idea... what if I make ANOTHER two JS files that delay for like 30 seconds while the installer runs and then they execute my regserver/unregserver files... Really sloppy but I mean it might work...
I am currently trying to make my app server run indefinitely with forever and nodemon. To do so, I am using the following command:
forever -c nodemon --exitcrash app.js
the problem is that the presence of forever module seems to affect the display of my app. Namely, whenever I run the app using forever, my login window styles are changed and the entire thing is shifted to the left side of the window. What is more, some of the app routes stop working. On the other hand, whenever I use a simple npm start or nodemon command, it works as expected.
Does anyone know why this may be happening? How could I make the server run continuously and not mess with the app itself?
P.S. It may be useful to mention that for some reason, my app only works upon running npm start and does not work properly when node app.js is run. I am unsure why that happens.
I understand when I run sails lift that the grunt tasks will run and put my assets in .tmp/. However, if I'm doing local development and want to make changes to some files in assets/js and refresh the page in the browser and see the updated code it seems I have to stop the server and re-lift the app.
I know there's a grunt watch task configured, and it seems like that is intended to handle this kind of thing. My questions are:
is the watch supposed to handle (for example) .js file changes and deliver the re-compilied/minified/concatenated/whatever'd scripts to .tmp/ without restarting the app?
if it is supposed to work like that, what common things should I check to troubleshoot why it's not?
As a side note, I'm running it with forever and simply ended up omitting **/assets/** from my .foreverignore file from what was listed in this answer. However, that still has the issue that the whole app is restarting when really I just need the asset pipeline run on change.
I disable Grunt during development and works fine for me.
This is how my .sailsrc looks:
"hooks":{
"grunt":false
},
"paths":{
"public":"assets"
}
Documentation:
http://sailsjs.org/documentation/concepts/assets/disabling-grunt
Is it possible to update a route,model or controller.js file without restarting the Node.js Server?.
I'm currently dealing with a client who wants constant changes to the application in a very frequent event. And the application deals with user session etc.. Whenever we make any changes to the application it requires a restart for the update to get reflect, which is very expensive in-terms of an high traffic situation.
I have seen some server application providing a feature called Rolling Restart but again I'm not sure whether it is a good way to maintain the user session across the restart event. Or do we have any other solution to deal with this kind of situation.
You can restart a server without downtime yes, I recommend you take a look at PM2 https://github.com/Unitech/pm2
You can have multiple instances of node running and when you set a restart it does it gradually, making that you don't have downtime, it also distributes load to the different instances running so it speeds up your app, hope this helps :-)
Nodemon is what I have used before and I was very happy with it.
Install
npm install -g nodemon
then run your app with
nodemon [your node app]
Done