I'm building a command line interface in node which connects to a background command line daemon. If no daemon is running, the first time the cli is called it will fork off the daemon using child_process.fork
The daemon needs to launch instances of electron BrowserWindow, but requiring electron is showing unusual behavior.
If running the daemon on it's own in the foreground, everything works smoothly; however in the background I get an empty module when requiring electron.
Printing Object.keys(require('electron')) to console shows the number sequence 0..84, and printing the results of require('electron') shows the string /path/to/electron/dist/electron
Printing out process.argv shows that the forked script is definitely being executed with electron.
I'm stumped. Any direction would be greatly appreciated.
Example:
launcher
#!/usr/local/bin/electron
const cp = require('child_process');
console.log();
const cld = cp.fork(__dirname+'/daemon',{
stdio:['inherit','inherit','inherit','ipc']
});
cld.on('message', (code) => {
code = parseInt(code);
cld.disconnect();
process.exit(code);
});
daemon
#!/usr/local/bin/electron
const fs=require('fs');
const log = (x)=>fs.appendFileSync('log',x+'\n\n');
log('');
if(!process.send) process.send = console.log;
log(process.argv);
const e = require('electron');
log(e);
log(Object.keys(e));
log(e.app);
process.send(0);
Resulting log file
*removed*/lib/thirdparty/node_modules/electron/dist/electron,*removed*/tmp/daemon
*removed*/lib/thirdparty/node_modules/electron/dist/electron
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84
undefined
Log file from running just daemon
*removed*/lib/thirdparty/node_modules/electron/dist/electron,./daemon
[object Object]
clipboard,nativeImage,shell,app,autoUpdater,BrowserView,BrowserWindow,contentTracing,crashReporter,dialog,globalShortcut,ipcMain,inAppPurchase,Menu,MenuItem,net,netLog,Notification,powerMonitor,powerSaveBlocker,protocol,screen,session,systemPreferences,TopLevelWindow,TouchBar,Tray,View,webContents,WebContentsView
[object App]
forked process by default set ELECTRON_RUN_AS_NODE=1 and will not expose any electron specific modules:
as https://github.com/electron/electron/issues/6656 says, you may need workaround by explicitly invoke process separately vice versa.
I try to run external application in node.js with child process like the following
var cp = require("child_process");
cp.exec("cd "+path+" && ./run.sh",function(error,stdout,stderr){
})
However when I try to run it stuck, without entering the callback
run.sh starts a server, when I execute it with cp.exec I expect it run asynchronously, such that my application doesn't wait until server termination. In callback I want to work with server.
Please help me to solve this.
cp.exec get the working directory in parameter options
http://nodejs.org/docs/latest/api/child_process.html#child_process_child_process_exec_command_options_callback
Use
var cp = require("child_process");
cp.exec("./run.sh", {cwd: path}, function(error,stdout,stderr){
});
for running script in the "path" directory.
The quotes are interpreted by the shell, you cannot see them if you just look at ps output.
i am writing an utility. One command of this utility is to run an external application.
var child_process = require('child_process');
var fs = require('fs');
var out = fs.openSync('.../../log/out.log', 'a');
var err = fs.openSync('.../../log/err.log', 'a');
exports.Unref = function(app, argv) {
var child = child_process.spawn(app, argv, {
detached: true,
stdio: [ 'ignore', out, err ]
});
child.unref();
//process.exit(0);
};
Currently:
$ utility run app --some-args // run external app
// cant enter next command while app is running
My Problem is that if i run this command, the terminal is locked while the "external" Application is running.
But the terminal window shouldn't be locked by the child_process.
i wanna run:
$ utility run app --some-args
$ next-command
$ next-command
The external Application (a desktop application) will be closed by hisself.
Like this:
$ subl server.js // this runs Sublime Text and passes a file to the editor
$ npm start // The terminal does not locked - i can execute next command while Sublime is still running
You know what i mean ^^?
Appending ['>>../../log/out.log', '2>>../../log/err.log'] to the end of argv instead of leaving two files open should work since it's the open file handles that are keeping the process alive.
Passing opened file descriptors in stdio in addition to detached: true will not work the way you expect because there is no way to unref() the file descriptors in the parent process and have it still work for the child process. Even if there was a way, I believe that when the parent process exited, the OS would clean up (close) the file descriptors it had open, which would cause problems for the detached child process.
The only possible way that this might have been able to work would have been by passing file descriptors to child processes, but that functionality was dropped several stable branches ago because the same functionality did not exist on some other platforms (read: Windows).
When using forever to run a node.js program as a daemon
i.e.
forever start myNodeTask
If the daemon (myNodeTask) decides it needs to exit, what is the correct way to do so?
If I just call process.exit() the program does terminate but it doesn't delete the forever log file, which leads me to believe that I need the program to exit in a more forever-friendly manner.
The node tasks I'm running are plain tcp servers that stream data to connected clients, not web servers.
The forever module always keeps the log files, even after a process has finished. There is no forever-friendly manner to delete those files.
But, you could use the forever-monitor module, which allow you to programatically use forever (from the docs):
var forever = require('forever-monitor'),
fs = require('fs');
var child = new (forever.Monitor)('your-filename.js', {
max: 3,
silent: true,
options: []
});
child.on('exit', function () {
console.log('your-filename.js has exited after 3 restarts');
// here you can delete your log file
fs.unlink('path_to_your_log_file', function (err) {
// do something amazing
});
});
child.start();
I run my app.js (node js application) via screen on my ec2 linux instance.
I'm trying to config my monitrc file and I need the app pidfile.
It's not in :
/var/run
(and there isn't a /var/www)
Would really appreciate it if someone has any idea where the pidfile is or how can I find it out..
Thank you!
in your app you can get the current pid number with process.pid so
var fs = require('fs');
fs.writeFile("/tmp/pidfile", process.pid);
and you get a pidfile in tmp
seems like there isn't a pid file created so I used forever-monitor in order to restart my app.js script in case of an error.
Looks like it is working.
What you need to do is npm install forever
and write server.js :
var forever = require('forever'),
child = new(forever.Monitor)('app.js', {
'silent': false,
'pidFile': '/var/run/app.pid',
'watch': false,
'options': ['8383'], // Additional arguments to pass to the script,
'sourceDir': '.', // Directory that the source script is in
'watchDirectory': '.', // Top-level directory to watch from.
'watchIgnoreDotFiles': true, // whether to ignore dot files
'watchIgnorePatterns': [], // array of glob patterns to ignore, merged with contents of watchDirectory + '/.foreverignore' file
'logFile': 'logs/forever.log', // Path to log output from forever process (when daemonized)
'outFile': 'logs/forever.out', // Path to log output from child stdout
'errFile': 'logs/forever.err'
});
child.start();
forever.startServer(child);
and then run it with - node server.js (I run it from ~/nodejs directory)
Still the pid file that supposed to be in /var/run isn't there, weird but I don't need monit anymore.
I still don't understand why I should additionally use upstart (like all the posts related suggested) anyhow when I tried to run upstart it didn't work