Aller au contenu principal
Julien Dubois

Comment garantir l'unicité d'un traitement

Ce billet a été produit dans le contexte d'Happyculture, il a pu être écrit en collaboration.

Voici une technique pour lancer un traitement automatisé une seule et unique fois sur un environnement.

Un jour on vous parlera de notre utilitaire Combawa qui nous permet de piloter la reconstruction d'un site Drupal - que ce soit en local ou sur les serveurs (de test, de production)-.

Ce que je voulais vous partager pour cette fois c'est une technique que nous utilisons pour jouer des instructions une seule fois. Nous avons les hook_update_N() et hook_post_update_NAME() à disposition lorsqu'il s'agit de travailler sur la base de données ou à plus haut niveau. Imaginez maintenant devoir faire des actions sur votre serveur telles qu'ajouter un cœur à Solr, vider des indexes, modifier une cron. Des actions facilement scriptables, pas forcément liées à Drupal et à garantir qu'elles ne seront jouées qu'une seule fois.

Pour y parvenir, voici le squelette d'un patron :

Voici le code pour lever le drapeau.

/**
* Raise a flag to reindex process.
*/
function project_post_update_1002(&$sandbox) {
  \Drupal::state('site_updates')->set('update_1002_reindexation_processed', 0);
}

Maintenant dans mon script de déploiement qui lance mes mises à jour, je dois évaluer la valeur de ce drapeau et s'il n'a jamais été joué, lancer les traitements associés.

Voici le code que nous exécutons, à vous de voir où le mettre dans le contexte de votre projet.

$DRUSH=./vendor/bin/drush
# Récupérer la valeur du drapeau
UPDATE_PROCESSED=$($DRUSH eval "print (int) \Drupal::state('site_updates')->get('update_1002_reindexation_processed', 0);")
if [[ $UPDATE_PROCESSED == 0 ]]; then
	$DRUSH search-api:clear global
	$DRUSH search-api:clear mag_authors
	$DRUSH search-api:index global
	$DRUSH search-api:index mag_authors
	# On n'oublie pas de modifier la valeur une fois les traitements lancés !
	$DRUSH eval "\Drupal::state('site_updates')->set('update_1002_reindexation_processed', 1)"
fi

Si vous aimez les frissons, vous pourriez aussi ne pas lever le drapeau dans le hook_post_update_NAME() et simplement vous fier au fait que \Drupal::state()->get() utilise le deuxième argument comme valeur par défaut.

Pour rebondir