Home » Tecnologia

A execução do cron.php no drupal não é executada

30 maio 2011 2 Comments

Percebi em um site de um cliente onde trabalho, a cron do drupal parou de rodar. Depois de analisar no watchdog (admin/reports/dblog) verifiquei que aparecia a seguinte mensagem:

“O agendador de tarefas excedeu o tempo limite e foi abortado.”

Por algum motivo, a cron estava com algum problema. Após fuçar muito na internet, descobrir que esse erro é por causa de um redirecionamento em um node com permissão de execução em php (pode acontecer também para blocos). Porém, como o site tem cerca de 10.000 nodes, como encontrar o bendito node que faz isso. Para isso, foi necessário mexer no core do drupal, apenas para localizar (deixei tudo normal como era antes, depois de resolver o problema).

Primeiro, na função “module_invoke_all” do arquivo include/module.inc adicionei o código que está comentado:

function module_invoke_all() {
  $args = func_get_args();
  $hook = $args[0];
  unset($args[0]);
  $return = array();
 
  foreach (module_implements($hook) as $module) {
    $function = $module .'_'. $hook;
    $result = call_user_func_array($function, $args);
#if ($hook == 'cron') watchdog('cron', "hit $module cron " . $result . " hook $hook $function, $args ");
    if (isset($result) && is_array($result)) {
      $return = array_merge_recursive($return, $result);
    }
    else if (isset($result)) {
      $return[] = $result;
    }
  }
 
  return $return;
}

Com esse código, tive a certeza que o problema era em um node. Para saber qual o node, tive que mexer no arquivo “module\node\node.module”  na função “node_update_index” e adicionar o código “watchdog(’cron’, “indexando o node $node->nid “);” no loop da função:

function node_update_index() {
  $limit = (int)variable_get('search_cron_limit', 100);
 
  // Store the maximum possible comments per thread (used for ranking by reply count)
  variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}'))));
  variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}'))));
 
  $result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, n.nid ASC", 0, $limit);
 
  while ($node = db_fetch_object($result)) {
	watchdog('cron', "indexando o node $node->nid ");
    _node_index_node($node);
  }
}

Após isso, é só chamar o cron.php e verificar no link “admin/reports/dblog”. Assim, consegui o nid do node. Ao editar esse node, descobrí que tinha um “header(’Location: user/register’)” nele. Não pode ter nem header(’Location’) nem drupal_goto, caso contrário a cron.php não irá executar. Para sanar o problema, bastou envolver o código header com um ” if (arg(0) == ‘node’) { ”

<? 
if (  $_SERVER["SCRIPT_NAME"] != '/cron.php' ) {
     header('Location: user/register'); 
     exit; 
} 
?>

A vida é assim, vivendo e apanhando. Opa, vivendo e aprendendo.

Uma dica de módulo é o http://drush.ws/resources e o http://drupal.org/project/supercron

Espero ajudar outras almas com esse post.

Até mais.

2 Comments »

  • Samuel said:

    Marco,

    Muito boa essa tua dica, solucionou o meu problema!
    Só o if($_SERVER["SCRIPT_NAME"]!=’/cron.php’) que não funciona pra mim.
    Alguma sugestão?

    Abraço

  • Marco Malaquias (author) said:

    Tenta dar um var_dump($_SERVER) e roda o cron.php no navegador. Assim dá para pegar o valor da variável $_SERVER["SCRIPT_NAME"]

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.