WordPress cron wp_schedule_single_event: la acción no siempre funciona

9 minutos de lectura

avatar de usuario
OhMad

Estoy registrando un evento como:

wp_schedule_single_event( time(), 'do_custom_hook', array( $body ) );

Por encima de eso, he añadido la siguiente acción:

add_action('do_custom_hook', 'process_custom_hook', 10);

function process_custom_hook($body){
    // custom code here
}

Sin embargo, a veces se activa la función process_custom_hook, mientras que otras veces, simplemente no lo hace (sin embargo, se activa la mayoría de las veces. Se pierde entre un 10 % y un 20 % de las veces)

El evento siempre regresa verdadero, lo que significa que debe haberse registrado.

Además, durante las pruebas, me aseguré de que los argumentos (cuerpo) siempre sean diferentes.

¿Alguna razón por la que esto puede ocurrir?

  • ¿Cuál es el propósito de programar un solo evento para “ahora”? ¿Por qué no simplemente ejecutas process_custom_hook en lugar de programar el evento? Además, ¿realmente te aseguraste $body fue diferente cada vez y no fue accidentalmente el mismo en el 10-20% de los casos?

    – Damocles

    24 de febrero de 2020 a las 10:59


  • Bueno. La cuestión es que estos eventos programados no los ejecuta exactamente un demonio cron… se disparan cuando los usuarios están viendo la página. Si process_custom_hook contiene código de bloqueo, esto de todos modos se ejecutará mientras un usuario intenta cargar la página; por lo tanto, aún afectará los tiempos de carga de la página de los usuarios. Para tales solicitudes de bloqueo, hay dos opciones: usar AJAX para que el usuario no se vea afectado directamente por el tiempo de procesamiento, o usar un trabajo cron real que invoque un archivo PHP que requiera wp-load.php y luego realizando el process_custom_hook cosas.

    – Damocles

    24 de febrero de 2020 a las 11:14

  • De mi investigación (wordpress.stackexchange.com/questions/141457/…) wp usa una solicitud paralela, que no bloqueará al usuario. Además, algunas pruebas que hice usando la función sleep() parecen mostrarme que la función no bloquea.

    – OhMad

    24 de febrero de 2020 a las 11:22


  • En mi experiencia, PHP time() La función no siempre está sincronizada con WordPress. Deberías usar current_time('timestamp') o variaciones de los mismos cuando se incluye en las funciones de WP

    – Jamie_D

    27 de febrero de 2020 a las 10:19


  • @Jamie_D gracias por el aporte, pero desafortunadamente ese no era el problema. lo raro es que el wp_schedule_single_event la función devuelve verdadero, lo que significa que debe haber sido programada, pero no se ejecuta ni aparecer en el cron. Algo debe estar diciéndole que omita el evento… ¿Existe tal vez una cantidad máxima de veces que se puede emitir un evento en un período de tiempo determinado? O, ¿deberían limpiarse los eventos (aunque los programe solo una vez y parezcan eliminarse automáticamente después de la ejecución)?

    – OhMad

    27 de febrero de 2020 a las 10:31


De el códice:

Tenga en cuenta que se ignorará la programación de un evento para que ocurra antes de 10 minutos después de un evento existente del mismo nombre, a menos que pase valores únicos para $args a cada evento programado.

Si su enlace personalizado solo funciona parte del tiempo, entonces esta podría ser una vía para considerar. Si necesita que el enlace se maneje de inmediato, entonces podría ser prudente considerar darle un nombre único o pasar valores únicos al enlace.

Si no necesita que su trabajo se ejecute de inmediato, entonces podría considerar utilizar wp_next_scheduled() para determinar cuándo se ejecutará el trabajo a continuación y configurar un trabajo para que se ejecute después del siguiente trabajo programado.

También vale la pena señalar que si esta tarea es algo que parece tener una lógica coherente detrás (como parece ser el caso), ¿por qué no almacenar la información del trabajo en la base de datos y ejecutar un trabajo cron cada 5-10 minutos para retomar? ¿Algún trabajo nuevo de la base de datos y manejarlo como tal? Esto evitaría tener que lidiar con el comportamiento de wp_schedule_single_event().

  • Gracias por la respuesta. Algunas cosas me parecen extrañas: incluso pasar los mismos argumentos a la función varias veces dentro del marco de tiempo de 10 minutos parece activarla (casi siempre). Por lo tanto, mis pruebas realmente no coinciden con el extracto del códice que publicaste. Y sí, se requiere que el anzuelo se manipule de inmediato. ¿Cómo haría para darle a un gancho un nombre único para cada ejecución? Puede valer la pena señalar que los argumentos son pares clave-valor en los que me aseguré de que al menos un valor siempre difería, pero las claves son las mismas.

    – OhMad

    5 de marzo de 2020 a las 9:50


  • Adición: para probar, pasé otro argumento a la función que consta de 40 caracteres aleatorios para verificar si los argumentos son el problema. Resulta que no lo son. La función todavía a veces no se ejecuta…

    – OhMad

    5 de marzo de 2020 a las 10:36

  • podrías correr add_action() antes de pasar un nombre a wp_schedule_single_event() y luego eliminar la acción con remove_action() al final del evento programado, esta es una sugerencia y no estoy seguro inicialmente si funcionaría en diferentes solicitudes (o con un sistema cron), por lo que podría requerirse más investigación allí.

    – megubyte

    5 de marzo de 2020 a las 16:16

  • Sí, según mi prueba rápida, esto parece causar algunos problemas debido a las diferentes solicitudes. Intentaré indagar más…

    – OhMad

    5 de marzo de 2020 a las 17:05

Según la documentación oficial sobre esta instancia,

La programación de un evento para que ocurra dentro de los 10 minutos posteriores a un evento existente con el mismo enlace de acción se ignorará a menos que pase valores únicos de $args para cada evento programado. que ha declarado que lo hizo, pero tal vez una doble verificación ayude.

Depende de cuándo un usuario visite el sitio, por lo que la acción se activará cuando alguien visite su sitio de WordPress si ha pasado el tiempo programado.

La documentación también dice que podría usar wp_next_scheduled() para evitar eventos duplicados y usar wp_schedule_event() para programar un evento recurrente.

El programa puede volver verdadero en ciertos casos en los que se ejecuta pero se ignoró. entonces se ejecutó pero fue ignorado.

Sugeriría un registro detallado de todo lo que se envía y recibe para que pueda ver por sí mismo si lo que está ocurriendo es lo mismo en lo que confía.

aquí hay algunos enlaces con problemas similares y documentación que puede consultar.

Espero que esto ayude. si no, averigüémoslo juntos.

De Documento de WordPress:

WP-Cron funciona al verificar, en cada carga de página, una lista de tareas programadas para ver qué debe ejecutarse. Cualquier tarea que deba ejecutarse se llamará durante la carga de esa página.

WP-Cron no se ejecuta constantemente como lo hace el cron del sistema; solo se activa al cargar la página.

Podrían ocurrir errores de programación si programa una tarea para las 2:00 p. m. y no se carga ninguna página hasta las 5:00 p. m.

Creo que su evento cron puede perderse porque no se carga la página a la hora programada.

Aquí hay una solución para su problema:
Conexión de WP-Cron en el programador de tareas del sistema

Como se mencionó anteriormente, WP-Cron no se ejecuta continuamente, lo que puede ser un problema si hay tareas críticas que deben ejecutarse a tiempo. Hay una solución fácil para esto. Simplemente configure el programador de tareas de su sistema para que se ejecute en los intervalos que desee (o en el momento específico que necesite). La solución más sencilla es utilizar una herramienta para realizar una solicitud web al archivo wp-cron.php…

En mi caso, este problema exacto ocurrió cuando también Woocommerce planificador de acciones estaba corriendo. Action Scheduler es un administrador de tareas cron que viene con Woocommerce, pero también con otros complementos como, por ejemplo, wp-mail-smtp.

Tuve exactamente el mismo problema y no pude averiguar qué estaba mal. Intenté depurar el código de WordPress y llegué a la conclusión de que cuando se programaba una tarea (es decir, el momento en que se agregaba a las tareas programadas) dentro de los 10 segundos de cada minuto completo, simplemente se eliminaba de inmediato. Parecía una especie de condición de carrera en la que el programador de acciones simplemente lo sacó de la pila sin que el cron normal de wp pudiera ejecutarlo, porque la tarea ya se había ido.

También debo decir que he configurado crontab llamando a wp-cron.php cada minuto (en lugar del ‘cron falso’ de WordPress).

cuando reemplacé wp_schedule_single_event con el as_enqueue_async_action función del Programador de acciones, ya no se eliminaron tareas.

Creo que una alternativa es desinstalar cualquier cosa que use el Programador de acciones, pero no lo he probado.

avatar de usuario
paulo boaventura

Está utilizando cron de WordPress, pero algunos complementos deshabilitan o impiden que CRON funcione. Mi recomendación en este caso es que cree este horario a través del Server Cron o instale un complemento para reafirmar su horario.

Tuve el mismo problema incluso fue un poco difícil de encontrar… Y como verán no tiene una actualización actual, pero para mí funciona. https://wordpress.org/plugins/wp-crontrol
&
https://br.wordpress.org/plugins/advanced-cron-manager/

puedes identificar que Cron quieres editar y así tener más precisión en tu edición. Hay otros complementos que pueden y deben estar relacionados con este. mencionaste sobre el horario de cron. Por eso te indiqué este. Entonces, puede conocer la configuración de Chrome en el calendario. WP Cron puedes editar tu horario de Cron

  • entonces usa este plugin que te pongo de referencia y no tendrás mas problemas

    –Paulo Boaventura

    3 de marzo de 2020 a las 19:34

  • Los complementos son para ver la actividad del trabajo cron. ¿Cómo podrían ayudar a resolver mi problema con el código? Además, ya tengo este último instalado.

    – OhMad

    4 de marzo de 2020 a las 9:30

  • entonces usa este plugin que te pongo de referencia y no tendrás mas problemas

    –Paulo Boaventura

    3 de marzo de 2020 a las 19:34

  • Los complementos son para ver la actividad del trabajo cron. ¿Cómo podrían ayudar a resolver mi problema con el código? Además, ya tengo este último instalado.

    – OhMad

    4 de marzo de 2020 a las 9:30

¿Ha sido útil esta solución?