diff --git a/utility/daemon/README.md b/utility/daemon/README.md index 95f41c16..fbc1736e 100644 --- a/utility/daemon/README.md +++ b/utility/daemon/README.md @@ -34,7 +34,9 @@ to restart the command automatically. Setting `msg.kill` to a signal name (e.g. SIGINT, SIGHUP) will stop the process - but if the restart flag is set it will then auto restart. -Sending `msg.start` will also re-start the process. Additional arguments can be specified in `msg.args`. +Sending `msg.start` will start the process, if not already running. Additional arguments can be specified in `msg.args`. + +Sending `msg.stop` will stop the process and prevent automatic re-start until reset with `msg.start`. **Note:** Some applications will automatically buffer lines of output. It is advisable to turn off this behaviour. For example, if running a Python app, the `-u` parameter will stop the output being buffered. diff --git a/utility/daemon/daemon.js b/utility/daemon/daemon.js index d3ab3817..7a1e011b 100644 --- a/utility/daemon/daemon.js +++ b/utility/daemon/daemon.js @@ -12,6 +12,7 @@ module.exports = function(RED) { this.op = n.op; this.redo = n.redo; this.running = false; + this.stopped = false; this.closer = n.closer || "SIGKILL"; this.autorun = true; if (n.autorun === false) { this.autorun = false; } @@ -32,16 +33,26 @@ module.exports = function(RED) { function inputlistener(msg) { if (msg != null) { - if (msg.hasOwnProperty("kill") && node.running) { + if (msg.hasOwnProperty("stop")) { + node.stopped = true; + if (node.running) { + node.child.kill(node.closer); + } + node.status({fill:"grey",shape:"ring",text:RED._("daemon.status.stopped")}); + } + else if (msg.hasOwnProperty("kill") && node.running) { if (typeof msg.kill !== "string" || msg.kill.length === 0 || !msg.kill.toUpperCase().startsWith("SIG") ) { msg.kill = "SIGINT"; } node.child.kill(msg.kill.toUpperCase()); } - else if (msg.hasOwnProperty("start") && !node.running) { - let args = ""; - if (msg.hasOwnProperty("args") && msg.args.length > 0) { - args = parseArgs(msg.args.trim()); + else if (msg.hasOwnProperty("start")) { + if (!node.running) { + let args = ""; + if (msg.hasOwnProperty("args") && msg.args.length > 0) { + args = parseArgs(msg.args.trim()); + } + runit(args); } - runit(args); + node.stopped = false; } else { if (!Buffer.isBuffer(msg.payload)) { @@ -111,7 +122,8 @@ module.exports = function(RED) { var rc = code; if (code === null) { rc = signal; } node.send([null,null,{payload:rc}]); - node.status({fill:"red",shape:"ring",text:RED._("daemon.status.stopped")}); + const color = node.stopped ? "grey" : "red"; + node.status({fill:color,shape:"ring",text:RED._("daemon.status.stopped")}); }); node.child.on('error', function (err) { @@ -138,7 +150,7 @@ module.exports = function(RED) { if (node.redo === true) { var loop = setInterval( function() { - if (!node.running) { + if (!node.running && !node.stopped) { node.warn(RED._("daemon.errors.restarting") + " : " + node.cmd); runit(); }