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:
time()
lors de la planification de l'événement? save_cpt()
et passez-les dans le paramètre $args
à wp_schedule_single_event()
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:
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:
- l'administrateur A édite la publication X, qui planifie la tâche cron avant la fin de celle-ci,
- 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.