it-swarm.com.de

WP Cron wird nach Ablauf der Zeit nicht ausgeführt

Das Ziel

Ich möchte mit wp_schedule_single_event( ) ein einzelnes Ereignis ausführen, das mir 8 Minuten nach dem Absenden eines Formulars durch den Benutzer eine E-Mail sendet.

Die Angelegenheit

Der folgende Code ist in meinem 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 ) );
}

Und der folgende Code wird verwendet, um schedule-event aufzurufen:

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

Nach einer Wartezeit von mehr als 8 Minuten war keine E-Mail in meinem Posteingang.

Was ich versucht habe

Mit dem Plugin Core Control kann man sehen, welche Cronjobs geplant sind.

Core Control screen

Nach ein paar Änderungen habe ich es geschafft, sie richtig zu machen. Wenn ich auf "Jetzt ausführen" drücke, bekomme ich tatsächlich eine E-Mail in meinem Posteingang.

Aber warum werden die Crons nicht ausgeführt, wenn ich meine Site nach 8 Minuten besuche? Was ist möglicherweise falsch an diesem Code? Ich muss sagen, dass ich WP Cron zum ersten Mal benutze.

Ich habe mehr versucht

Nachdem der Kommentar von vancoder id entschieden hat, zu testen, ob der Code funktioniert, füge ich den folgenden Code direkt in den functions.php ein:

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

Der Nachteil dieses Codes ist, dass der Benutzer eine andere Seite aufrufen muss, bevor dieser Code ausgeführt wird. Aber auf der anderen Seite funktioniert das auch nicht, das wäre nicht meine erste Ausgabe ...

16
Mike Madern

Kannst du bitte zuerst bestätigen, dass keine Caching-Plugins aktiviert sind? Caching-Plugins können Cron-Jobs stören, da Ihren Besuchern keine Live-Seite, sondern eine zwischengespeicherte Version Ihrer Seite bereitgestellt wird.

Wenn Sie ein Caching-Plugin aktiviert haben, können Sie eine Ihrer Seiten auswählen und den Einstellungen Ihres Caching-Plugins für diese Seite einen Ausschluss hinzufügen, damit es niemals zwischengespeichert wird.

Dann müssen Sie manuell einen Cron-Job erstellen (mit cpanel, wenn Sie sich in einer gemeinsam genutzten Hosting-Umgebung befinden, oder über das Terminal, wenn es sich um einen VPS/dedizierten Server handelt), der diese Seite alle paar Minuten aufruft.

Ich hoffe das hilft!

8
WPMU-DEV Ari

Definieren Sie zunächst Ihre benutzerdefinierten Zeitpläne für Cron-Jobs.

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

Sie müssen entscheiden, wo und wann die Veranstaltung stattfinden soll.

Hier ist nur ein Codebeispiel, mit dem eine benutzerdefinierte Klassenmethode aufgerufen wird:

$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.
));

Hier ist der Code, der das Ereignis tatsächlich plant:

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

Jetzt müssen Sie nur noch den Namen Ihrer benutzerdefinierten Cron-Aufgabe aufrufen. In diesem Beispiel lautet der Name der Cron-Aufgabe custom_imap_import.

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

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

In diesem Beispiel wird also $this->do_imap_import(); alle 30 Minuten aufgerufen (vorausgesetzt, Sie haben genügend Zugriffe auf Ihre Website).


Anmerkungen

Erfordert einen Seitenbesuch, damit Ihr Cron zum richtigen Zeitpunkt ausgelöst wird.

Beispiel: Wenn Sie eine Aufgabe in 30-Minuten-Intervallen geplant haben, aber 4 Stunden lang niemand Ihre Site besucht, wird Ihr Cron-Job erst ausgelöst, wenn dieser Besucher 4 Stunden später zu Ihrer Site kommt. Wenn Ihre Aufgabe wirklich alle 30 Minuten ausgeführt werden muss, empfiehlt es sich, einen legitimen Cron-Job über Ihren Webhosting-Anbieter einzurichten, um Ihre Website in den gewünschten Abständen zu besuchen.

WordPress Cron-Jobs machen Ihre Website nicht langsam!

Vielleicht überlegen Sie, was die Besucher abwarten müssen, bis das Skript ausgeführt wird, wenn die Ausführung des Cron-Skripts viel Zeit in Anspruch nimmt. Nee! Wie kann das möglich sein? Wenn Sie sich die Datei wp-cron.php ansehen, finden Sie eine Zeile

ignore_user_abort(true);

Es ist eine php.ini-Konfiguration, die festlegt, dass das Skript nicht mehr ausgeführt wird, wenn Sie das Laden der Site/des Skripts beenden.

Wenn Sie sich die Datei wp-includes/cron.php ansehen, finden Sie eine Zeile wie diese:

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

Das bedeutet, dass WordPress nur 0,01 Sekunden auf das Auslösen der Ausführung wartet und dann abbricht. Da Sie jedoch ignore_user_abort auf true gesetzt haben, wird das Skript ausgeführt. Diese Funktionalität ist ein großer Vorteil, um große Skripte in WordPress-Cron-Jobs auszuführen.

Für die Hilfe verfügbare Funktionen:

14
Michael Ecklund

Mit WordPress Cron können Sie Aufgaben planen, die jedoch nur ausgeführt werden, wenn eine Anfrage an die Site gestellt wird. Bei jeder Anforderung, die WordPress erhält, wird geprüft, ob Cron-Aufträge zu verarbeiten sind. In diesem Fall wird eine Anforderung an /wp-cron.php?doing_wp_cron zur asynchronen Verarbeitung des Auftrags ausgelöst. Wenn der geplante Start eines Jobs ohne Anforderung verstrichen ist, wird der Cron-Prozess nicht gestartet.

Da Sie Ihre geplanten Jobs anzeigen und ausführen können, gibt es möglicherweise keine Anforderungen, die den Start des Cron-Jobs auslösen, insbesondere wenn Sie ein Caching-Plugin verwenden. Die beste Möglichkeit, dies in einen regelmäßigeren Zeitplan zu verschieben, besteht darin, die Standardprüfung in WordPress zu deaktivieren und crontab zu verwenden.

Fügen Sie dem wp-config.php Folgendes hinzu, um die Standardüberprüfung zu deaktivieren (was die Leistung auf der Clientseite etwas verbessern kann):

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

Als Nächstes erstellen Sie eine Aufgabe, um die Seite wp-cron.php einmal pro Minute abzurufen, um alle Jobs im Back-End zu verarbeiten. Geben Sie in der Befehlszeile crontab -e ein und fügen Sie eine Zeile hinzu, die wie folgt aussieht:

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

Überprüfen Sie jedes Plugin, das Wordpress verbirgt.

Wie kann man feststellen, ob dies das Problem ist?

  1. Navigieren Sie zu http (s): //yoursite.com/wp-cron.php. Sie sollten eine leere Seite sehen. Ein völlig leerer.
  2. Außerdem müssen Sie in einem Cron Job Manager eine Zeit unter "Nächste Ausführung" sehen:  Cron job scheduled - if wp-cron.php works properly  (nicht nur der Text "In Warteschlange" - sondern eine bestimmte Zeit - für einige Einträge ist "In Warteschlange" manchmal in Ordnung, aber wenn es das einzige ist, was Sie sehen -> Ihr Cron funktioniert nicht.)

+1. Glauben Sie keinen Plugins, die "prüfen, ob cron funktioniert" - z. WP Das Cron Status Checker Plugin hat gezeigt, dass cron funktioniert. Tatsächlich aber nicht.  Whatever it shows - believe your eyes and not this plugin! 

Fazit: Wenn es sich um einen 404-Fehler handelt, deaktivieren Sie a) nicht nur das Zwischenspeichern von Plugins, wie von anderen empfohlen, sondern auch alle Plugins, die Wordpress verbergen.

0
Peter Cz

Stellen Sie sicher, dass DISABLE_WP_CRON nicht in Ihrer Konfiguration festgelegt ist.

Andernfalls deaktivieren Sie alle Plugins (außer der Kernsteuerung - obwohl ich wp-crontrol verwenden würde) und prüfen Sie, ob Ihre Kernaufträge funktionieren. In diesem Fall tritt irgendwo eine Plug-in-Störung auf.

Versuchen Sie in ähnlicher Weise, zu einem Standardthema für 20-Jährige zu wechseln.

Wenn keines davon einen Unterschied macht, ist es wahrscheinlich ein Hosting-Problem.

0
vancoder