wake-up-neo.net

Wie kann sichergestellt werden, dass immer nur ein wp_cron () ausgeführt wird?

Ich habe ungefähr 20 wp_cron() Funktionen wie den folgenden Code. Fast alle Crons werden stündlich ausgeführt. einige sind täglich.

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  //Complex Code
}

Um die Serverleistung zu verbessern und um nicht ständig Server-Limit-Nachrichten von Hosting-Unternehmen zu erhalten, möchte ich sicherstellen, dass jeweils nur ein Cron ausgeführt wird ... Ist dies möglich?


Die derzeit akzeptierte Antwort ist großartig, aber ich habe folgende Frage, deshalb starte ich eine Prämie für diese Frage.

Bitte lesen Sie zuerst die akzeptierte Antwort.

Nehmen wir an, Cron 1 läuft, mein Code von cron2 läuft nicht, weil wir noch innerhalb der 5 Minuten sind oder der erste Cron noch läuft, aber wegen wp_schedule_event( time(), 'hourly', 'my_task_hook' );, der für cron2 läuft, denke ich, dass WordPress als Cron2 läuft betrachtet wird code von cron2 code nie laufen lassen ..... oder habe ich etwas falsch verstanden?

Ja, es ist möglich...

Und um ehrlich zu sein, ist es oft sehr wichtig, dies zu tun ... WP Scheduler neigt manchmal dazu, Probleme zu verursachen, wenn Cron-Aufgaben lang sind ...

Wie löse ich dieses Problem?

Ich verwende Transients API um Semaphoren zu implementieren ...

Hier ist der Code:

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  // if some other my_task is already running, stop
  if ( get_transient( 'my_task_function_semaphore' ) ) return;

  // set semaphore for 5 minutes
  set_transient( 'my_task_function_semaphore', true, 5*60 );

  // DO YOUR STUFF

  delete_transient( 'my_task_function_semaphore' );
}

Warum verwende ich in diesem Fall Transienten? Weil:

  • Sie sind Teil von WP.
  • Sie sind einfach zu bedienen und effizient.
  • Sie verursachen keine Deadlocks. Nehmen wir an, meine Cron-Task kann getötet werden (es kann ein Fehler auftreten oder sie läuft zu lange und wird getötet usw.). In diesem Fall wird das Semaphor nicht gelöscht, sodass alle zukünftigen Aufgaben nicht funktionieren. Die Verwendung von Transienten löst dieses Problem, da Transienten nach einiger Zeit gelöscht werden.

Und was ist, wenn es viele verschiedene Aktionen gibt?

Nehmen wir also an, es gibt viele verschiedene Cron-Tasks, die niemals zur selben Zeit ausgeführt werden sollten, aber wir möchten, dass sie alle ausgeführt werden ...

Wenn wir die Lösung mit Semaphor verwenden und für alle diese Aufgaben nur ein Semaphor verwenden, werden einige davon möglicherweise nie ausgeführt. Was ist dann zu tun?

In diesem Fall sollten Sie Ihr Denken ändern. Sie haben keine unabhängigen Aufgaben, aber eine Reihe von Aufgaben zu erledigen. Sie sollten es also auf diese Weise implementieren.

So:

  1. Sie fügen eine Art Warteschlange hinzu (Sie können ein Array verwenden und als Option speichern oder eine benutzerdefinierte DB-Tabelle hinzufügen).
  2. Sie verwenden Ihr aktuelles WP Cron-Stundenereignis, um Aufgaben zur Warteschlange hinzuzufügen.
  3. Sie fügen zweite WP Cron-Tasks hinzu, die viel häufiger ausgeführt werden und die Tasks einzeln aus der Warteschlange "fressen". Diese "Esser" -Aufgabe sollte ein Semaphor verwenden, um sicherzustellen, dass jeweils nur eine Aufgabe ausgeführt wird.
9