web-dev-qa-db-fra.com

WP cron: quand programmer un événement unique

J'ai un type d'article personnalisé ('my_cpt') et, sur save_post_my_cpt, je dois éventuellement apporter un grand nombre de modifications à d'autres articles (en fonction de l'état de l'article, par exemple post_status, des valeurs post_meta et des termes issus de la taxonomie personnalisée). Ces autres modifications devront peut-être être effectuées dans d'autres blogs multisites. Par conséquent, la fonction appelée sur save_post_my_cpt peut prendre environ une minute pour terminer l'exécution ... ce qui n'est pas très "convivial" pour l'utilisateur admin qui modifie le contenu.

J'organise les choses pour que ces autres modifications se produisent via WP Cron. Donc j'ai:

add_action ('save_post_my_cpt', 'save_cpt') ;

function
save_cpt ($post_id)
{
    if (defined ('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return ;
        }

    // do stuff related to saving post meta, etc
    // e.g., update_post_meta ($post_id, '_some_meta_name', $_REQUEST['some_meta_name'], true) ;

    // schedule an event to do the modifications of other posts
    // see below for question related to the time this cron job will be scheduled
    $time = time () ;
    wp_schedule_single_event ($time, 'my_cron_hook', array ($post_id)) ;

    return ;
}

add_action ('my_cron_hook', 'cron_func') ;

function
cron_func ($post_id)
{
    $post = get_post ($post_id) ;

    // get_blogs_that_might_need_to_be_modified() returns an array of blog_id's that
    // MIGHT have other posts related to $post that need to be modified

    // get_posts_in_that_blog_that_need_to_be_modified() returns an array of posts
    // related to $post that need to be modified

    // modify_post() returns a modified version of a related post based on the
    // current state of $post

    // the details of these functions aren't relevant to this question
    foreach (get_blogs_that_might_need_to_be_modified ($post) as $blog_id) {
        switch_to_blog ($blog_id) ;

        foreach (get_posts_in_that_blog_that_need_to_be_modified ($post) as $other_post) {
            $other_post = modify_post ($post) ;
            wp_update_post ($other_post) ;
            }

        restore_current_blog () ;
        }
}

J'espère que tout le monde est avec moi jusqu'à ce point. Ma question concerne le moment auquel je devrais planifier ce travail cron une fois.

Si je programme le travail cron pour s’exécuter "immédiatement" (comme dans le code ci-dessus), puis-je être assuré que, dès que cron_func() sera appelé, TOUTES les mises à jour de la base de données relatives à la sauvegarde de mon CPT seront terminées (car appelé dans cron_func() devra lire l'état modifié de $post_id)?

Planifier l'événement "immédiatement" semble fonctionner correctement dans mon environnement de développement local (où je suis le seul à accéder au site).

Je me demande si je ne rencontrerai probablement aucun problème lorsque le site fonctionnera dans un environnement de production très chargé (c.-à-d. Avec un certain nombre d'utilisateurs administrateurs modifiant simultanément le contenu sur le back-end, tandis -utilisateurs frappent le front-end)

Deux alternatives que je considère:

  1. ajouter un décalage à time() lors de la planification de l'événement?
    1. par exemple, programmez-le pour qu'il s'exécute 1 minute plus tard
    2. si j'ai besoin de le faire, devinez combien de temps je devrais attendre
  2. rassemblez toutes les informations dont j'ai besoin dans save_cpt() et passez-les dans le paramètre $args à wp_schedule_single_event()
    1. Je préférerais ne pas aller dans cette voie, car la collecte de ces informations pourrait prendre un certain temps, ce qui ralentirait les choses pour l'utilisateur admin.
    2. y a-t-il des "dépenses" (mémoire, etc.) pour transmettre une grande quantité d'informations à un travail via cron?

Y a-t-il d'autres considérations que je devrais prendre en compte? Par exemple, quelle est la probabilité que cela se produise lorsque:

  1. administrateur A édite le post X, qui planifie le travail cron
  2. avant que le travail cron ne se termine, l'administrateur B administre une autre modification afin de publier X

Si je programme le travail cron pour qu'il soit exécuté "immédiatement" (comme dans le code ci-dessus), puis-je être assuré que cron_func () est appelée à TOUTES les mises à jour de la base de données liées à la sauvegarde de mon CPT (depuis les fonctions appelées dans cron_func () devront lire l'état modifié de $ post_id)

Oui. Le crochet save_post est déclenché après que le message ait été réellement enregistré. Ainsi, le cron_func obtiendra l'état modifié de la publication. Vous n'avez besoin d'aucune alternative pour cela.

Y a-t-il d'autres considérations que je devrais prendre en compte? Par exemple, quelle est la probabilité que cela se produise lorsque:

  1. l'administrateur A édite la publication X, qui planifie la tâche cron avant la fin de celle-ci,
  2. l'administrateur B effectue une autre modification pour publier X

Si le travail cron prend du temps, il est très possible de rencontrer un tel problème. Pour résoudre ce problème, vous pouvez lever un indicateur (il peut s'agir d'un post méta) lors de la création de la tâche périodique et l'effacer à la fin de la tâche périodique. Vous voudrez peut-être désactiver l'édition de la publication tant que le drapeau est présent pour une publication.

1
sakibmoon