WP Cron non si esegue allo scadere del tempo


16

L'obiettivo. il gol

Voglio utilizzare wp_schedule_single_event( )per eseguire un singolo evento che mi invia un'e-mail 8 minuti dopo che l'utente invia un modulo.

Il problema

Il seguente codice è nel mio functions.php:

function nkapi_send_to_system( $args ) {
  wp_mail( 'xxx', 'xxx', $args );
}

add_action( 'nkapi_send', 'nkapi_send_to_system' );

function schedule_event( $id ) {
  wp_schedule_single_event( current_time( 'timestamp' ) + 480, 'nkapi_send', array( $id ) );
}

E il seguente codice viene utilizzato per chiamare schedule-event:

schedule_event( $_SESSION['insert_id'] ); // the $_SESSION var contains an INT

Dopo aver atteso più di 8 minuti non c'era una e-mail nella mia casella di posta.

Quello che ho provato

Con il plug-in Core Control è possibile vedere quali cron job sono programmati.

Schermata di controllo principale

Dopo un paio di modifiche sono riuscito a renderle abbastanza corrette, e meglio, quando premo "Esegui ora", in realtà ricevo un'e-mail nella mia casella di posta.

Ma perché i cron non vengono eseguiti quando visito il mio sito dopo 8 minuti. Cosa c'è di sbagliato in questo codice? Devo dire che questa è la prima volta che utilizzo WP Cron.

Ho provato di più

Dopo il commento di Vancoder ID ho deciso di verificare se il codice funziona se inserisco il seguente codice direttamente nel functions.php:

function schedule_event( $id ) {
  wp_schedule_single_event( time(), 'nkapi_send', array( $id ) );
}

if ( isset( $_SESSION['insert_id'] ) ) {
  if ( ! array_key_exists( 'insert_scheduled', $_SESSION ) || $_SESSION['insert_scheduled'] != $_SESSION['insert_id'] ) {
    schedule_event( $_SESSION['insert_id'] );
    $_SESSION['insert_scheduled'] = $_SESSION['insert_id'];
  }
}

L'aspetto negativo di questo codice è che l'utente deve andare su un'altra pagina prima che questo codice venga eseguito. Ma d'altra parte, neanche questo funziona, quindi non sarebbe il mio primo problema ...


1
Dove e come viene schedule_event( $_SESSION['insert_id'] );sparato?
Vancoder,

Un shortcode include un file separato (con un modulo in esso) in una pagina, quando quel modulo viene pubblicato la pagina viene ricaricata, lo stesso file quindi esegue il schedule_event( ), diciamo in cima al file incluso caricato dal shortcode.
Mike Madern,

Fare qualsiasi lavoro cron? wp_version_check etc?
vancoder,

Non ho avuto nessun crone al lavoro. Quale potrebbe essere il problema?
Mike Madern,

Per confermare - anche i processi cron core falliscono?
vancoder

Risposte:


8

Innanzitutto, puoi confermare che non hai abilitato i plug-in di cache? I plug-in di cache possono interferire con i processi cron perché ai tuoi visitatori non viene pubblicata una pagina live ma una versione cache della tua pagina.

Se hai un plug-in di cache abilitato, puoi scegliere una delle tue pagine, aggiungere un'escussione alle impostazioni del tuo plug-in di cache per quella pagina in modo che non venga mai memorizzato nella cache.

Quindi dovrai creare manualmente un cron job (usando cpanel se sei in un ambiente di hosting condiviso o dal terminale se è un VPS / server dedicato) che visiterà quella pagina ogni pochi minuti.

Spero che aiuti!


Ho un plug-in di cache abilitato! W3 Total Cache per la precisione
Mike Madern

14

Innanzitutto, definisci le tue pianificazioni cron personalizzate.

add_filter('cron_schedules', array($this, 'cron_schedules'));

public function cron_schedules($schedules){
    $prefix = 'cron_';// Avoid conflict with other crons. Example Reference: cron_30_mins
    $schedule_options = array(
        '30_mins' => array(
            'display' => '30 Minutes',
            'interval' => '1800'
        ),
        '1_hours' => array(
            'display' => 'Hour',
            'interval' => '3600'
        ),
        '2_hours' => array(
            'display' => '2 Hours',
            'interval' => '7200'
        )
    );
    /* Add each custom schedule into the cron job system. */
    foreach($schedule_options as $schedule_key => $schedule){
        $schedules[$prefix.$schedule_key] = array(
            'interval' => $schedule['interval'],
            'display' => __('Every '.$schedule['display'])
        );
     }
     return $schedules;
}

Devi decidere dove e quando programmare effettivamente l'evento.

Ecco solo un esempio di frammento di codice, che effettua una chiamata a un metodo di classe personalizzato:

$schedule = $this->schedule_task(array(
    'timestamp' => current_time('timestamp'), // Determine when to schedule the task.
    'recurrence' => 'cron_30_mins',// Pick one of the schedules set earlier.
    'hook' => 'custom_imap_import'// Set the name of your cron task.
));

Ecco il codice che pianifica effettivamente l'evento:

private function schedule_task($task){
    /* Must have task information. */
    if(!$task){
        return false;
    }
    /* Set list of required task keys. */
    $required_keys = array(
        'timestamp',
        'recurrence',
        'hook'
    );
    /* Verify the necessary task information exists. */
    $missing_keys = array();
    foreach($required_keys as $key){
        if(!array_key_exists($key, $task)){
            $missing_keys[] = $key;
        }
    }
    /* Check for missing keys. */
    if(!empty($missing_keys)){
        return false;
    }
    /* Task must not already be scheduled. */
    if(wp_next_scheduled($task['hook'])){
        wp_clear_scheduled_hook($task['hook']);
    }
    /* Schedule the task to run. */
    wp_schedule_event($task['timestamp'], $task['recurrence'], $task['hook']);
    return true;
}

Ora, tutto ciò che devi fare è effettuare una chiamata al nome della tua attività cron personalizzata. In questo esempio il nome dell'attività cron è custom_imap_import.

add_action('custom_imap_import', array($this, 'do_imap_import'));

public function do_imap_import(){
    // .... Do stuff when cron is fired ....
}

Quindi, in questo esempio, $this->do_imap_import();viene chiamato ogni 30 minuti (supponendo che il traffico sul tuo sito Web sia sufficiente).


Appunti

Richiede una visita alla pagina affinché il tuo cron si attivi al momento giusto.

Esempio: se hai pianificato un'attività a intervalli di 30 minuti, ma nessuno visita il tuo sito per 4 ore, il tuo cron job non verrà licenziato fino a quando quel visitatore non arriva al tuo sito 4 ore dopo. Se hai davvero bisogno che la tua attività venga licenziata ogni 30 minuti, allora ti consigliamo di impostare un cron job legittimo tramite il tuo provider di web hosting per visitare il tuo sito web agli intervalli desiderati.

I lavori cron di WordPress non rallentano il tuo sito web!

Forse stai pensando che cosa succede se l'esecuzione del cron-script richiede molto tempo, i visitatori dovranno attendere fino a quando lo script non viene eseguito. No! Come può essere possibile? Se guardi il wp-cron.phpfile troverai una linea

ignore_user_abort(true);

È una php.iniconfigurazione che imposta che se si interrompe il caricamento del sito / script lo script non smetterà di essere eseguito.

Se guardi il wp-includes/cron.phpfile troverai una linea come questa:

wp_remote_post( $cron_url, 
array('timeout' => 0.01,
 'blocking' => false, 
 'sslverify' => apply_filters('https_local_ssl_verify', true)) );

Ciò significa che WordPress attenderà solo 0,01 secondi per l'attivazione dell'esecuzione, quindi si interromperà, ma come hai impostato ignore_user_abortper truelo script verrà eseguito. Questa funzionalità è un enorme vantaggio per eseguire script di grandi dimensioni nei lavori cron di WordPress.

Funzioni disponibili per l'aiuto:


6
Questa è una risposta straordinariamente completa, che per quanto posso vedere, non riesce a rispondere alla domanda reale - motivo per cui falliscono tutte le attività pianificate (comprese le attività principali).
vancoder

Questa risposta è guidare l'utente nella giusta direzione per comprendere e pianificare correttamente le attività cron di WordPress.
Michael Ecklund,

4
Questo mi ha sicuramente aiutato a capire molto i programmi cron con WordPress
Mike Madern,

2
Michael, dovresti rispondere più spesso. Grande +1
kaiser

1
Penso che WP_Cronusi GMT sotto il cofano, come il resto del WP, quindi sarebbe meglio programmare il primo evento time()invece di current_time().
Ian Dunn,

3

WordPress Cron ti consente di pianificare attività, ma verranno eseguite solo se è stata effettuata una richiesta al sito. Per ogni richiesta ricevuta da WordPress verificherà se ci sono processi cron da elaborare e, in tal caso, attiva una richiesta in /wp-cron.php?doing_wp_cronmodo asincrono per elaborare il processo. Se l'avvio pianificato di un lavoro passa senza una richiesta, il processo cron non verrà avviato.

Dato che sei in grado di vedere ed eseguire i tuoi lavori pianificati, è possibile che non ci siano richieste che attivano l'avvio del cron job, specialmente se stai usando un plugin di cache. L'opzione migliore per scaricare questo su una pianificazione più regolare è disabilitare il controllo predefinito in WordPress e utilizzarlo crontab.

Innanzitutto per disabilitare il controllo predefinito (che può aiutare un po 'con le prestazioni lato client), aggiungere quanto segue a wp-config.php:

// Disable default check for WordPress cron jobs on page loads
define( 'DISABLE_WP_CRON', true );

Quindi si crea un'attività per recuperare la wp-cron.phppagina una volta al minuto per elaborare tutti i lavori sul back-end, dalla riga di comando immettere crontab -ee quindi aggiungere una riga simile alla seguente:

*/1 * * * * /usr/bin/curl --silent http://example.com/wp-cron.php?doing_wp_cron=$(date +\%s.\%N) >/dev/null 

2
Se non dai un valore a doing_wp_cron, è molto probabile che a volte i lavori vengano eseguiti due volte. Usare doing_wp_cron=$(date +\%s.\%N)per impedirlo.
Alexander Garden,

0

Verifica che DISABLE_WP_CRON non sia impostato nella tua configurazione.

In caso contrario, prova a disabilitare tutti i plug-in (tranne il controllo core, anche se vorrei usare wp-crontrol) e vedere se i tuoi lavori principali funzionano. In tal caso, si verificano interferenze del plug-in da qualche parte.

Allo stesso modo, prova a passare a un tema standard di ventenni.

Se nessuno di questi fa alcuna differenza, è probabile che sia un problema di hosting.


Non ho DISABLE_WP_CRONimpostato il mio wp-config.php, proverò più cose e tornerò più tardi
Mike Madern,

0

Controlla eventuali plugin che nascondano Wordpress.

Come vedere se questo è il problema?

  1. Vai a http (s): //yoursite.com/wp-cron.php Dovresti vedere una pagina vuota. Uno completamente vuoto.
  2. Inoltre devi vedere in un cron job manager un tempo in "Prossima esecuzione": Cron job pianificato - se wp-cron.php funziona correttamente (non solo il testo "In coda" - ma un determinato tempo - per alcune voci "In coda" va bene a volte, ma se è l'unica cosa vedi -> il tuo cron non funziona.)

+1. Non credere a nessun plugin che "controlla se cron funziona", ad esempio il plugin WP Cron che controlla lo stato ha mostrato che cron funziona. Ma in realtà no. Qualunque cosa mostri, credi ai tuoi occhi e non a questo plugin!

Conclusione: se si tratta dell'errore 404, disattiva a) non solo la memorizzazione nella cache dei plug-in come altri suggeriscono b) ma anche tutti i plug-in che nascondono Wordpress.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.