Skip to main content

php cronjob interruption



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


Comments

  1. 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

    ReplyDelete
  2. If this is a bash script, you can trap the ctrl+c signal like so:

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

    trap is_borked SIGINT


    It'd be up to you to keep track (via variable?) at which step this happened, if you need some kind of a cleanup.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.