Impedir que um Script PHP seja executado ao mesmo tempo no Cron

Impedir que um Script PHP seja executado ao mesmo tempo no Cron

Estou construindo um script de sincronia de banco de dados que deve rodar de 5 em 5 minutos na cron do linux. O problema é que ele pode acabar durando mais do que cinco minutos então pesquisando uma forma de evitar que o script seja executado novamente antes que o anterior termine encontrei a solução no link abaixo e coloco aqui com pequenas alterações:

http://abhinavsingh.com/blog/2009/12/how-to-use-locks-in-php-cron-jobs-to-avoid-cron-overlaps/

Crie um arquivo chamado CronHelper.php e adicione o código abaixo (eu coloquei na mesma pasta do meu script cron):

<?php
define('LOCK_DIR', __DIR__ . '/');
define('LOCK_SUFFIX', '.lock');

class CronHelper {
    private static $pid;

    function __construct() {
        
    }

    function __clone() {
        
    }

    private static function isrunning() {
        $pids = explode(PHP_EOL, `ps -e | awk '{print $1}'`);
        if (in_array(self::$pid, $pids)) {
            return TRUE;
        }
        return FALSE;
    }

    public static function lock() {
        global $argv;
        
        $path_parts = pathinfo($argv[0]);

        $lock_file = LOCK_DIR . $path_parts['basename'] . LOCK_SUFFIX;

        if (file_exists($lock_file)) {
            //return FALSE;
            // Is running?
            self::$pid = file_get_contents($lock_file);
            if (self::isrunning()) {
                error_log("==" . self::$pid . "== Já está em progresso...");
                return FALSE;
            } else {
                error_log("==" . self::$pid . "== O job anterior foi interrompido abruptamente...");
            }
        }

        self::$pid = getmypid();
        file_put_contents($lock_file, self::$pid);
        error_log("==" . self::$pid . "== Trava adquirida, processando o job...");
        return self::$pid;
    }

    public static function unlock() {
        global $argv;

        $lock_file = LOCK_DIR . $argv[0] . LOCK_SUFFIX;

        if (file_exists($lock_file)) {
            unlink($lock_file);
        }

        error_log("==" . self::$pid . "== Soltando a trava...");
        return TRUE;
    }

}

Para utilizado coloque todo o código do cron dentro do if:

<?php
require 'CronHelper.php';

if(($pid = cronHelper::lock()) !== FALSE) {
    /*
     * O código do seu cron job vai aqui!
     */

    cronHelper::unlock();
}

?>
Tags: , , , ,

Sobre o autor

Um desenvolvedor web veterano que está sempre a procura de novas tecnologias que facilitem o desenvolvimento de aplicativos ricos para a internet. Louco por tecnologia, games e Linux.

Deixe uma resposta