Cómo funciona el cron en Drupal
Carlos — Mar, 12/08/2008 - 23:14
Ged de Drupalweb me lanza el reto de explicar un poco cómo funciona el cron en Drupal. En realidad lo hizo hace unos días pero no lo vi hasta ayer, pero bueno, supongo que más vale tarde que nunca.
Realmente pide saber más sobre el cron y sobre el ping, pero yo he escogido el cron. El ping se lo dejo a Pedro o a Daniel o a quien quiera.
Cómo introducción estaría bien saber que es el cron (de la wikipedia):
En el sistema operativo Unix, cron es un administrador regular de procesos en segundo plano (demonio) que ejecuta programas a intervalos regulares (por ejemplo, cada minuto, día, semana o mes). Los procesos que deben ejecutarse y la hora en la que deben hacerlo se especifican en el archivo crontab.
Cron se podría definir como el "equivalente" a Tareas Programadas de Windows. Los usuarios habilitados para crear su archivo crontab se especifican en el archivo cron.allow. De manera análoga, los que no lo tienen permitido figuran en /etc/cron.d/cron.deny, o /etc/cron.deny, dependiendo de la versión de unix.
Es decir, que es un programa que ejecutará en los intervalos que le digamos un determinado programa. Esto se hace usando el comando crontab -e o desde el panel de control de tu hosting. Lo siguiente es una linea del cron:
30 * * * * /home/carlos/mi_script
Esto hará que cuando lo minutos sean igual a 30, las horas cualquiera, el día cualquiera y el mes cualquiera se ejecuta /home/carlos/mi_script. Es decir, que el primer número indica los minutos, el segundo las horas, el tercero los días, el cuarto los meses y el quinto el día de la semana (me olvidé de este, gracias FeKuLa). Un asterisco vale de comodín o podemos poner más de un valor usando un coma cómo separador. Por ejemplo el siguiente código que ejecutará mi_script cuando los minutos sean 0, 15, 30 o 45, es decir, cada cuarto de hora:
0,15,30,45 * * * * /home/carlos/mi_script
Vale, ¿y ahora cómo unimos esto al cron de Drupal? Es fácil, en Drupal hay un archivo llamado cron.php (curioso el nombre) que es el que hemos de configurar para que el cron lo ejecute, por lo que añadiremos algo así:
0 * * * * wget -O - -q -t 1 http://www.midominio.com/cron.php
Con esto se ejecutará cada hora. Si estás en un hosting compartido es mejor poner un minuto diferente de 0, uno que no sea normal, así cuando se ejecute no habrá otros programas ejecutados por el cron e irá más rápido (o por lo menos no ayudará a sobrecargarse el servidor, algo más habitual de lo normal). Dependiendo de nuestra web tal vez sea necesario que se ejecute más o menos veces. También es posible que wget no esté en el path por lo que habrá que poner la ruta completa, normalmente suele ser /usr/bin/wget.
Recuerda que esta linea no se añade en el cron.php de Drupal, se ha de añadir usando el comando crontab -e (sólo para expertos) o usando tu panel de control de hosting.
Ahora sólo falta por saber que hace el fichero cron.php aunque primero hay que saber lo que es un hook en drupal. En la documentación de Drupal pone (traducido más o menos por mi):
Permite a los módulos interactuar con el núcleo de Drupal.
El sistema de módulos de Drupal esta basado en el concepto de "hooks". Un hook es una función de PHP a la que llamamos foo_bar(), donde "foo" es el nombre del módulo (cuyo nombre de archivo es también foo.module) y "bar" es el nombre del hook. Cada hook tiene una serie de parámetros predefinidos y el tipo de variable que devuelve.
Para ampliar Drupal, un módulo simplemente implementa un hook. Cuando Drupal desea permitir la intervención desde los módulos determina que módulos implementan un hook y ejecuta ese hook en los módulos habilitados que lo implementen.
Ummm, creo que no está demasiado bien explicado o lo he traducido mal. Intentaré explicarlo con mis propias palabras. Un hook no es más que una función de un módulo pero que se llama de una manera especial. Por ejemplo, si estoy haciendo un módulo que se llama carlosrincon y quiero que ese módulo tenga un bloque con mi foto tendré que usar el hook_block por lo que llamaré a mi función carlosrincon_block.
Entonces cuando Drupal quiera ver todos los bloques disponibles mirará de entre todos los módulos habilitados las funciones que se llamen nombremodulo_block y encontrará el mio.
Pues todo esto venía por que existe el hook_cron que cuando el fichero cron.php se ejecuta Drupal busca en todos los módulos que hayan implementado el hook_cron y ejecuta el hook. Así por ejemplo la búsqueda indexa el contenido cada vez que se ejecuta el cron.php por que tiene una función que se llama search_cron()
<?php
function search_cron() {
// We register a shutdown function to ensure that search_total is always up
// to date.
register_shutdown_function('search_update_totals');
// Update word index
foreach (module_list() as $module) {
module_invoke($module, 'update_index');
}
}
?>
Bueno, espero poder haber aclarado las dudas pero si hay alguna más para eso están los comentarios.
Buenas Carlos, Una
aitiba (no verificado) — Jue, 14/08/2008 - 05:45Buenas Carlos,
Una preguntilla: dentro de mi cron.php he anadido esta linea al final:
"0,10,20,30,40,50 * * * * wget -O - -q -t 1 http://localhost/cron.php", con eso se supone que en los minutos 0,10,20,30,40,50 se ejecutara el cron no? una vez sea ejecutado, automaticamente indexaria el contenido o habria que poner algo mas?
Gracias. Un saludo. aitor
Si tienes activado el módulo
Lokiyo (no verificado) — Jue, 14/08/2008 - 09:45Si tienes activado el módulo 'search', que es el de búsquedas, y por lo tanto el encargado de indexar el contenido, no tienes que hacer nada más, puesto que se ejecutará el hook llamado 'search_cron' (cron para el módulo search) que comprobará si hay contenido que indexar y generará los índices para las búsquedas de contenido.
Creo que esta pregunta viene dada porque no se explicó del todo el funcionamiento del cron de Drupal.
Por un lado, ha quedado claro, que hay un programa en cualquier sistema UNIX, llamado 'cron' que ejecuta otros programas cada cierto intervalo de tiempo.
Por otro lado, se ha explicado que en drupal hay un hook que permite a los módulos 'asignar' (por así decirlo) tareas al cron (es decir, permite asignar tareas que se ejecutarán cada cierto intervalo de tiempo).
Lo que no se ha explicado detalladamente es que para ejecutar todos los 'hook_cron' existe un fichero que es el mencionado 'cron.php', pero que este fichero no se ejecuta sólo, y por eso hay que configurarlo en el 'cron' con una línea similar a "0,10,20,30,40,50 * * * * wget -O - -q -t 1 http://example.com/cron.php".
Lo que hace esta línea es 'ejecutar' el fichero cron.php que le indiquemos y este fichero, busca todos los hook_cron existentes en la instalación de drupal y los ejecuta.
Bueno, me ha quedado un post muy largo, pero espero que haya aclarado cosas ;)
PD: creo que una línea más simple para el cron es esta: "0,10,20,30,40,50 * * * * GET http://ircapajedrez.org/cron.php /dev/null". Tal vez no funciona en todos los hostings, pero es la que uso yo, y sin problemas.
Releyendo el comentario, veo
Lokiyo (no verificado) — Jue, 14/08/2008 - 10:03Releyendo el comentario, veo otra confusión:
"dentro de mi cron.php he añadido esta linea al final"
¡No debes modificar el cron.php bajo ningún concepto!
Hay que diferenciar lo que es el cron: servicio que ejecuta programas o comandos a intervalos definidos; de lo que es el cron.php de Drupal: fichero que llama a todos los hook_cron implementados.
Como se dice en el artículo, el cron se configura usando el comando crontab. Ahora bien, si estás en un host compartido, seguramente no tengas acceso a usar estos comandos, con lo que debes configurar el cron desde tu CPANEL.
En el CPANEL tienes un formulario donde elijes las horas a las que quieres que se ejecute el cron.php de Drupal.
Para ello seleccionas las horas, y pones como comando a ejecutar "GET http://example.com/cron.php /dev/null".
Por supuesto, tienes que cambiar "example.com", por la dirección de tu web.
Muchas gracias Lokiyo por las
Carlos — Jue, 14/08/2008 - 10:39Muchas gracias Lokiyo por las correcciones :)
Buenas Carlos y demas,
aitiba (no verificado) — Vie, 15/08/2008 - 21:41Buenas Carlos y demas,
Gracias @Carlos y @Lokiyo por la aclaración. Me ha sido de gran ayuda, ya que, no entendia muy bien el funcionamiento del cron en drupal.
Un saludo. aitor
Pues de nada :)
admin — Vie, 15/08/2008 - 22:54Pues de nada :)
Hola Carlos Saludos, Bueno
4jotas (no verificado) — Jue, 09/07/2009 - 07:39Hola Carlos
Saludos,
Bueno tengo un sitio en drupal 6.12 y me salio este error... no se como solucionarlo
--
Cron GET http://sitio.com/cron.php /dev/null
De: Cron Daemon (root@server.com)
Enviado: lunes, 06 de julio de 2009 1:04:37
Para: mail@dom.com
500 Can't connect to sitio.com:80 (Bad hostname 'sitio.com')
---
Haber si me guias como resolver este inconveniente.
att,
4jotas
PD. Como hago para actualizar de 6.12 a 6.13(no se como hacerlo soy nuevo en drupal) me sale una advertencia para actualizar.
Evidentemente, tienes que
Lokiyo (no verificado) — Jue, 09/07/2009 - 21:13Evidentemente, tienes que sustituir "sitio.com" por el nombre de dominio de tu web...
Hola Lokiyo. Creo que no
4jotas (no verificado) — Jue, 09/07/2009 - 23:29Hola Lokiyo.
Creo que no explique bien, entonces envio el mensaje completo que me envio el servidor:
--
Cron GET http://negociosefectivos.com/cron.php /dev/null
De: Cron Daemon (root@dim.inc.com)
Enviado: lunes, 06 de julio de 2009 1:04:37
Para: jrr@hotmail.com
500 Can't connect to negociosefectivos.com:80 (Bad hostname 'negociosefectivos.com')
--
La verdad no se a que se deba,
En Cpanel de mi hosting le puse esta linea en el cron
GET http://negociosefectivos.com/cron.php /dev/null
cada 4min - cada hora - todos los dias - cada mes - cada dia entresemana
En mi .htaccess le puse esto
RewriteCond %{HTTP_HOST} !^www\.negociosefectivos\.com$ [NC]
RewriteRule (.*) http://www.negociosefectivos.com/$1 [R=301,L]
Para que todo el trafico llegue a www.negociosefectivos.com
Recien viendolo bien este codigo debe ir asi
GET http://negociosefectivos.com/cron.php /dev/null
o asi
GET http://negociosefectivos.com/cron.php/dev/null
Con ese espacio o sin espacio, yo lo puse con espacio en el cron jobs estandar de Cpanel.
o debo poner
GET http://www.negociosefectivos.com/cron.php/dev/null
porque en htaccess le puse que todo se vaya a www.negociosefectivos.com
Ahora tambien tiene algo que ver que yo aun no actualize el drupal 6.12 a 6.13 o no
tiene nada que ver.
(Como se hace esa actualizacion? teniendo yo Cpanel, mysql y phpmyadmin)
Espero tu respuesta y comentarios.
att,
4jotas
He probado de varias formas y
Andy (no verificado) — Jue, 28/10/2010 - 18:25He probado de varias formas y me ha funcionado de varias formas:
Así funciona bien y omite el reporte por e-mail, es la sintaxis recomendada en la documentación: http://drupal.org/cron
wget -O - -q -t 1 http://www.midominio.com/cron.php
Así también funciona pero me manda un e-mail y guarda un archivo aunque aún no sé donde, jaja.
wget http://www.midominio.com/cron.php