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';