web-dev-qa-db-fra.com

Comment s'assurer que seulement un wp_cron () s'exécute à la fois?

J'ai environ 20 fonctions wp_cron() comme le code suivant. Presque tous les crons fonctionnent toutes les heures; quelques-uns sont quotidiens.

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
}

Pour augmenter les performances du serveur, et pour ne pas continuer à recevoir des messages de la part de la société d'hébergement hébergeant une limite de serveur, je veux m'assurer qu'un seul cron s'exécute à la fois ... Est-ce possible?


La réponse acceptée actuellement est excellente, mais j'ai la question suivante, c'est pourquoi je commence une prime pour cette question.

Veuillez lire la réponse acceptée au début.

Supposons que Cron 1 s'exécute, mon code de cron2 ne fonctionnera pas car nous sommes toujours dans les 5 minutes ou le premier cron est toujours en cours d'exécution, mais à cause de wp_schedule_event( time(), 'hourly', 'my_task_hook' ); s'exécutant pour cron2, je pense que WordPress considère que cron2 s'exécute ..... code de code cron2 ne fonctionne jamais ..... Ou j'ai mal compris quelque chose?

Oui c'est possible...

Et pour être honnête, il est souvent très important de faire cela ... WP Le planificateur a parfois tendance à poser problème, lorsque les tâches périodiques sont longues ...

Alors, comment je résous ce problème?

J'utilise API transitoires pour implémenter des sémaphores ...

Voici le 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' );
}

Pourquoi est-ce que j'utilise des transitoires dans ce cas? Parce que:

  • Ils font partie de WP.
  • Ils sont faciles à utiliser et efficaces.
  • Ils ne vont pas provoquer des impasses. Disons que ma tâche cron peut être tuée (une erreur peut se produire, ou elle dure trop longtemps et est tuée, etc.). Dans ce cas, le sémaphore ne sera pas supprimé et toutes les tâches futures ne fonctionneront pas. L'utilisation de transitoires résout ce problème car après un certain temps, les transitoires seront supprimés.

Et s'il y a beaucoup d'actions différentes à faire?

Donc, disons qu'il y a beaucoup de tâches cron différentes, qui ne devraient jamais être exécutées en même temps, mais nous voulons toujours qu'elles s'exécutent toutes ...

Si nous utilisons la solution avec un sémaphore et si nous utilisons un seul sémaphore pour toutes ces tâches, il est possible que certaines d'entre elles ne s'exécutent jamais. Alors que faire alors?

Dans ce cas, vous devriez changer votre façon de penser. Vous n'avez pas de tâches indépendantes, mais une file d'attente de tâches à effectuer. Donc, vous devriez le mettre en œuvre de cette façon.

Alors:

  1. Vous ajoutez une sorte de file d'attente (vous pouvez utiliser un tableau et le stocker en tant qu'option, ou ajouter une table de base de données personnalisée).
  2. Vous utilisez votre événement horaire WP cron en cours pour ajouter des tâches à la file d'attente.
  3. Vous ajoutez une deuxième WP tâches cron qui s'exécute beaucoup plus souvent et "mange" les tâches de la file d'attente une par une. Cette tâche "mangeur" ​​doit utiliser un sémaphore pour garantir l’exécution d’une seule tâche à la fois.
9
Krzysiek Dróżdż