I'm building a database synchronization script that should run every 5 minutes in Linux's cron. The problem is that it can end up taking longer than five minutes, so while researching a way to prevent the script from running again before the previous one finishes, I found the solution at the link below and post it here with small changes:
http://abhinavsingh.com/blog/2009/12/how-to-use-locks-in-php-cron-jobs-to-avoid-cron-overlaps/
Create a file called CronHelper.php and add the code below (I put it in the same folder as my cron script):
<?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;
}
}
To use it, put all the cron code inside the if:
<?php
require 'CronHelper.php';
if(($pid = cronHelper::lock()) !== FALSE) {
/*
* O código do seu cron job vai aqui!
*/
cronHelper::unlock();
}
?>
Comments 0
No comments yet.