прерывание работы php cronjob


У меня есть работа в php, которая вычисляет несколько бизнес-правил (например: чистый оборот, валовой оборот, расчетный оборот и т. Д.... С использованием стандартного отклонения и других математических алгоритмов)

Это задание cron вызывает несколько вызовов cron 3 php-скрипта с использованием exec

Для каждого вызова я запускаю процесс в фоновом режиме и сообщаю системе, что запущены задания x. например:

Вот моя логика

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

Что мне нужно исправить, так это

Если кто-то запускает задание вручную и отменяет его (ctrl+c) или что-то плохое произойдет в cron (фатальная ошибка или не удается подключиться к бд) или что-нибудь еще (например, недостаточно памяти)

Я хочу остановить эту работу и рассказать, что произошло и когда она прекратилась, чтобы я мог начать с того места, где она была.

Возможно ли это? спасибо

 17
Author: joel, 2011-11-15

2 answers

Вот простой код, который вы должны попробовать/отладить:

<?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";

Если cronjob работает нормально, вы получите:

shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
Done
shutdown function
shutdown::destruct

Если вы получите фатальную ошибку:

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

Если вы убьете процесс:

kill <processid>

shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
SIG: handle shutdown tasks
Done
shutdown function
shutdown::destruct

Вы также можете использовать posix_kill(posix_getpid(), <signal you like>); в каждом случае.

читать больше:

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

 34
Author: Book Of Zeus, 2011-11-16 01:01:28

Если это сценарий bash, вы можете перехватить сигнал ctrl+c следующим образом:

is_borked()
{
    echo "Somebody set up us the bomb"
    exit
}

trap is_borked SIGINT

Вам нужно будет отслеживать (с помощью переменной?), на каком этапе это произошло, если вам нужна какая-то очистка.

 0
Author: pp19dd, 2011-11-15 13:32:48