5

So this is as much a theoretical question as a language-specific one, but consider this:

I need PHP to execute a rather system-intensive process (using PHP exec();) that will be running in the background, but then when a user leaves that specific page, the process will be killed.

I quickly realized that a dead man's switch would be an easy way to implement this since I'm not making use of any session variables or other server-side variables, which could end up looking like:

if($_SERVER['REQUEST_URI'] !== 'page_with_session.php'){
    //Instead of 'session_destroy();' this would be used to kill said process
}

In any case, a while loop in PHP, resetting a timer in a Python script or re-calling said script every 15 seconds so that it doesn't get to the end and kill the process. However, when the user leaves the page, the script will have been called but not able to reset before killing the process.

Are there any gaping holes in this idea? If not, how would the implementation in PHP/JS look? The order I see it working in would be:

  1. Page is hit by user
  2. <?php exec('killer.py') ?>
  3. killer.py:
    1. Listen for 20 seconds - If no response...
    2. os.system('pkill process')
  4. <?php while(true){sleep(15); exec('killer.py no_wait_dont');} ?>

Any thoughts you guys have would be greatly appreciated!

Mason

MasonWinsauer
  • 673
  • 3
  • 14
  • 32
  • How do you plan to detect that the user left the page? Obviously they might leave the page AND your site altogether - your `if` statement isn't going to do you much good in that case. – Madbreaks Aug 02 '12 at 21:07
  • 2
    @Madbreaks was typing at the same time as me ... Anyway, I'd think you would need some Javascript to ping the server every 15 seconds (maybe less to allow for lag), but then what happens if the connection goes down temporarily, but the user is still on the page? Then, if the connection comes up before the user leaves, your process will have been killed, but from the user's perspective they never left. – GreenMatt Aug 02 '12 at 21:11
  • @Madbreaks - This is a way to circumvent detecting users leaving the page by setting script that will kill the process if it isn't pinged within a certain amount of time. Even then, if they were to leave both, the server would complete the requested script and exit normally. – MasonWinsauer Aug 02 '12 at 21:19
  • @GreenMatt - This is for a web app that would be working locally, so the chances of the server losing contact is very slim. Thanks for the idea, though - A JS message 'Sever Connection Lost: Refreshing Stream' would work well =) – MasonWinsauer Aug 02 '12 at 21:19

2 Answers2

3

Javascript is a lot easier, and about as safe (that is, not much).

Just write a javascript ping function that, once every 10 seconds, posts something to ping.php (via ajax). This ping.php would log when the last ping was received in the user session (say in $_SESSION['last_ping'])

You can check for user activity from other pages by comparing $_SESSION['last_ping'] to the current time. You would have to pepper your runtime-intensive pages with this, but it would certainly work.

tucuxi
  • 17,561
  • 2
  • 43
  • 74
2

Implement a heartbeat in JS. If it stops for more than a certain time then kill the subprocess:

  • js sends a request
  • php/python start the subprocess in a background and return pid to js
  • js pings php/python with given pid
  • php/python signals the subprocess corresponding to pid via IPC e.g., by sending SIGUSR1
  • if subprocess doesn't receive a signal in time; it dies i.e., there is a constant self-destruct countdown in the subprocess

If you can't add the self-destruct mechanism to the subprocess then you need a watcher process that would receive signals and kill the subprocess. It is less reliable because you need to make sure that the watcher process is running.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • So here's a question - How do you get the python process to reset every time it's hit by the `setInterval($.post())` portion? Right now, it loads multiple instances and waits until the `time.sleep()` of the Python script completes... – MasonWinsauer Aug 08 '12 at 19:18
  • Also, if this should be another question (that would be helpful to others in a general sense), let me know and I will post a link to it here. – MasonWinsauer Aug 08 '12 at 19:20
  • 1
    @MasonWinsauer: It depends on how the timeout is implemented. See [various ways to implement timeout in Python](http://stackoverflow.com/questions/4417962/stop-reading-process-output-in-python-without-hang). For example, for the last method you could just reset `start` variable (assign to current time). Note: not all methods are applicable if the Python process is launched by Apache. – jfs Aug 08 '12 at 19:54