Para impedir que o cron processe em duplicidade, vamos implementar um hacker no código que cancele a execução do próximo cron, caso exista um cron ainda em processamento.
Para implementar isso, siga os seguintes passos:
1) Abra o arquivo cronlib.php
Localize e abra o seguinte arquivo
MOODLE_INSTALL_DIR/lib/cronlib.php
2) Edite a função cron_run()
Localize a função function cron_run() essa função fica aproximadamente na linha 35 a 519
function cron_run() {
global $DB, $CFG, $OUTPUT;
.......
}Adicione no inicio da função depois do código global $DB, $CFG, $OUTPUT; o seguinte código:
//check exist cron running
$sql ="SELECT COUNT(id) AS countrecord FROM {$CFG->prefix}log WHERE module = 'monitorcron' AND action='cron_start' ";
$result=$DB->get_record_sql($sql);
if($result->countrecord > 0) {
//add to log not process cron
$crondto=new object();
$crondto->time=time();
$crondto->module='monitorcron';
$crondto->action='cron_not_processed';
$crondto->userid=2;
$crondto->course=1;
$crondto->ip=getremoteaddr();
$crondto->url="cron_id_".time();
$DB->insert_record('log', $crondto);
echo "exist other cron running";
return null;
}
//star log new cron
$crondto=new object();
$crondto->time=time();
$crondto->module='monitorcron';
$crondto->action='cron_start';
$crondto->userid=2;
$crondto->course=1;
$crondto->ip=getremoteaddr();
$crondto->url="cron_id_".time();
$DB->insert_record('log', $crondto);
//get id of new cron
$sql ="SELECT id FROM {$CFG->prefix}log WHERE module = 'monitorcron' AND action='cron_start' AND url='".$crondto->url."' ";
$result=$DB->get_record_sql($sql);
$crondto->id=$result->id;
echo "cron id ". $crondto->id ." started ";
Esse código verifica se existe algum cron em execução. Se existir não processa.
No final da função que fica aproximadamente na linha 519, antes de fechar a função adicione esse código:
// add to log end of cron
$crondto->cmid=time();
$crondto->action='cron_end';
$crondto->info=$crondto->cmid-$crondto->time;
if( $crondto->id>0){
$DB->update_record('log', $crondto);
}
echo "cron id ". $crondto->id. " end";
Esse trecho registra o encerramento do cron, usando a mesma chave do registro de log que iniciou o cron.
Veja a função com com os códigos inseridos:
function cron_run() {
global $DB, $CFG, $OUTPUT;
//código adicionado. registrar log de inicio
//star log new cron
$crondto=new object();
$crondto->time=time();
$crondto->module='monitorcron';
$crondto->action='cron_start';
$crondto->userid=2;
$crondto->course=1;
$crondto->ip=getremoteaddr();
$crondto->url="cron_id_".time();
$DB->insert_record('log', $crondto);
//get id of new cron
$sql ="SELECT id FROM {$CFG->prefix}log WHERE module = 'monitorcron' AND action='cron_start' AND url='".$crondto->url."' ";
$result=$DB->get_record_sql($sql);
$crondto->id=$result->id;
echo "cron id ". $crondto->id ." started ";
//código da lógica da função
.......
//código adicionado. Registra log do fim da execução
// add to log end of cron
$crondto->cmid=time();
$crondto->action='cron_end';
$crondto->info=$crondto->cmid-$crondto->time;
if( $crondto->id>0){
$DB->update_record('log', $crondto);
}
echo "cron id ". $crondto->id. " end";
}Salve as alterações feitas no arquivo
3) Consultor log com SQL
Para rastrear o log do cron, execute o seguinte comando SQL:
Verifique se existe cron em processamento
SELECT COUNT(id) AS countrecord FROM mdl_log WHERE module = 'monitorcron' AND action='cron_start'
Encerre manualmente o processamento do cron
UPDATE mdl_log SET action='cron_end_manual' WHERE module = 'monitorcron' AND action='cron_start';
Consultar log de cron
SELECT id,url AS idcontnrol,action,time AS timestart, cmid AS timeend, info AS duration FROM mdl_log WHERE module = 'monitorcron';