i have a cronjob in php that calculates few business rules (eg: net rev, gross rev, estimated rev, etc... using standard deviation & other math algo)
this cronjob calls multiple cron calls 3 php scripts using exec
for each calls i start a process in background and tell the system that jobs x started. eg:
here's my logic
start 
 main cron start - message
  cron sub 1 start - message
  run cron sub 1
  cron sub 1 end - message
  wait until cron sub 1 stop
  process stuff  
  cron sub 2 start - message
  run background cron sub 2 // this will automaticaly send a message when this jobs end
  cron sub 3 start - message
  run background cron sub 3 // this will automaticaly send a message when this jobs end
 main cron end - message
end
what i need to fix is this
if someone runs the job manually and cancel it (ctrl+c) or something bad happen in the cron (fatal error or cannot connect to db) or anything else (like not enough memory)
i want to stop the cronjob and tell what happen and when it stopped so i can start back where it was.
is it possible? thanks
Here's a simple code you have to try/debug:
<?php
ignore_user_abort(false);
function shutdown() {
  echo "shutdown function\n";
}
register_shutdown_function('shutdown');
class shutdown {
  function __construct() {
    echo "shutdown::construct\n";
  }
  function __destruct() {
    echo "shutdown::destruct\n";
  }
}
$s = new shutdown();
declare(ticks = 1);
function sig_handler($signo) {
  switch ($signo) {
    case SIGTERM:
      echo "SIG: handle shutdown tasks\n";
      break;
    case SIGHUP:
      echo "SIG: handle restart tasks\n";
      break;
    case SIGUSR1:
      echo "SIG: Caught SIGUSR1\n";
      break;
    case SIGINT:
      echo "SIG: Caught CTRL+C\n";
      break;
    default:
      echo "SIG: handle all other signals\n";
      break;
  }
  return;
}
echo "Installing signal handler...\n";
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP,  "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
echo "Generating signal SIGTERM to self...\n";
# killing the script using bad memory allocation
/*
ini_set('memory_limit', '1K');
$data = '';
for($i = 0; $i < 1000; $i++) {
  $data .= str_repeat($i . time(), time());
}
*/
# simulating CTRL+C
// for($i = 0; $i < 100000000; $i++) {  } // don't forget to press CTRL+C
echo "Done\n";
if the cronjob runs normally you will get:
shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
Done
shutdown function
shutdown::destruct
if you get a Fatal error:
shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
PHP Fatal error:  Possible integer overflow in memory allocation (11 * 1321404273 + 1) in /var/www/domain.com/php.php on line 51
shutdown function
if you kill the process:
kill <processid>
shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
SIG: handle shutdown tasks
Done
shutdown function
shutdown::destruct
you can use posix_kill(posix_getpid(), <signal you like>); in each cases also.
read more:
http://php.net/manual/en/function.pcntl-signal.php
http://en.wikipedia.org/wiki/Signal_%28computing%29
http://users.actcom.co.il/~choo/lupg/tutorials/signals/signals-programming.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With