MacGapProject / MacGap2

MacGap 2
MIT License
1.2k stars 84 forks source link

MacGap.Task not terminating when app does #46

Open senorflor opened 9 years ago

senorflor commented 9 years ago

First, thanks for putting this framework together; allowed me to turn a web app into a POC .app going in one day, despite almost zero Objective-C/Xcode experience. I'm grateful for the work you've put in here!

I am working on a .app that kicks off a bundled long-running subprocess via MacGap.Task. I'd like the subprocess to run only as long as the .app does, and then shutdown when the .app does. Unfortunately, when I quit the .app, this subprocess is orphaned and runs indefinitely. Is this expected behavior? Relevant code and observations below:

Task setup and launch:

// Launch client
var myTask = MacGap.Task.create(
  resources_path+"/the_subprocess",
  function(res) {
    if (res.status !== 0) {
      window.alert("Subprocess failed; exiting.");
      MacGap.terminate();
    }
  }
);
myTask.arguments  = ["an_arg"];
myTask.currentDirectoryPath = resources_path;
myTask.waitUntilExit = true; // have tried this both ways
myTask.launch();

Observations:

According to ps, the subprocess launches with the .app's pid as it's ppid and has no signals masked. It communicates with the .app as expected while the .app is running. Unfortunately, whether I Quit or Force Quit the .app from the Finder, or SIGINT or SIGKILL it from the terminal, the child process is orphaned, assigned to init, and continues running.

(I also tried registering unload and beforeunload handlers to intercept shutdown at the WebKit level and force the cleanup, to no avail, and saw https://github.com/MacGapProject/MacGap1/issues/111, but was not sure what to do based on the inconclusiveness of that issue and my own inexperience in Objective-C/all things NSObject.)

Any insight would be greatly appreciated–thanks!

rawcreative commented 9 years ago

So I can dig into this, what are you running via the Task command? Is it a custom script, a system cmd? Is it interacting with the app at all, or just running in the background? Just trying to get a handle on what you're doing so I can debug it properly.

I honestly never intended on the task command being used to launch any long running processes which is why there currently isn't anything in place to terminate any existing tasks prior to quit, but I'll definitely put something in to cleanup on quit, or at least fire an event so the app can handle it.

Handling termination of a running task if the app crashes is another story though, and there actually isn't a generalized way of handling it reliably and safely in all scenarios, and is even difficult in a normal cocoa app.

senorflor commented 9 years ago

Tim: cheers and thanks for getting back!

We are running a custom long-running resource handling process (not signal masked or daemonized in any way, though). We communicate with it via https (it was once the native component for a web-only app). I can replicate all the relevant aspects of the orphaned process behavior with a simple bash script:

#!/usr/bin/env bash

while true; do
  echo yo
  sleep 1
done

If I kick that off as a MacGap.Task on OS 10.9 or 10.10, then quit the MacGap app in any manner, the process continues afterwards as a child of init.

Let me know if this is enough info, and how I can help out.