Catching interruption in PHP cron jobs

Posted on Saturday January 21, 2012 / by Eric Potvin

Cron jobs are very useful for data summarization or processing data that requires time to execute. Logging these jobs are important and without them it might be hard to find out if they ran properly. These jobs might sometimes crash or unexpectedly stop running. Under these circumstance, it might be hard to find out where the script stopped and what was processed.

Here's a simple way to implement a way to find out what happen if a cron job fail using the sig_handler PHP function.

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

// don't forget to press CTRL+C
for($i = 0; $i < 100000000; $i++) {  }

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 /path/to/cron/script.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