Douple appel du pipeline trig_calculer_prochain_postdate
Bonjour,
je rencontre (parfois) un problème de race condition sur le pipeline trig_calculer_prochain_postdate
qui peut se voir appeler 2X de suite si par hasard 2 requêtes utilisateurs arrivent en même temps sur le serveur.
edit: je suis sur spip branche 4.1
Le point d'entrée est dans la fonction cache_valide
avec le code suivant:
if (
isset($GLOBALS['meta']['post_dates'])
and $GLOBALS['meta']['post_dates'] == 'non'
and isset($GLOBALS['meta']['date_prochain_postdate'])
and $now > $GLOBALS['meta']['date_prochain_postdate']
) {
spip_log('Un article post-date invalide le cache');
include_spip('inc/rubriques');
calculer_prochain_postdate(true);
}
Puis dans la fonction calculer_prochain_postdate
nous avons (je simplifie):
- un ou plusieurs appels à
publier_branche_rubrique
- le déclenchement du pipeline
trig_calculer_prochain_postdate
- la mise à jour de
GLOBALS['meta']['date_prochain_postdate']
Ce que j'arrive à reproduire parfois, c'est :
- une 1ère requête tombe, je suis en plein traitement dans la fonction
monplugin_trig_calculer_prochain_postdate
- une 2ème requête tombe:
- Et là, ma meta
GLOBALS['meta']['date_prochain_postdate']
n'a pas encore été mise à jour car l'autre thread est toujours dans le traitement du pipeline - la condition dans
cache_valide
est vraie - on réappelle
calculer_prochain_postdate
, qui lui même va réappelermonplugin_trig_calculer_prochain_postdate
- j'ai donc un double appel qui me provoque un bug, même si c'est particulier à ce que fait ma fonction.
- Et là, ma meta
Ceci dit, je suis partagé sur l'action à mener, notamment parce que ce pipeline n'est pas documenté. Donc déjà il faudrait trancher sur: "est ce que ce comportement est problématique ou pas". Si c'est assumé que oui, ça peut être appelé n fois, alors ça reviendrait à l'écrire dans la doc quelque part et que c'est à l'utilisateur du pipeline de prendre ses précautions. Personnellement, j'aurais tendance à dire que c'est un problème car fonctionnellement parlant, on ne voit pas bien pourquoi ce pipeline pourrait être déclenché plusieurs fois à cause d'un seul et unique post-datage. C'est contre-intuitif (enfin je trouve).
Du coup, je pense qu'il faudrait calculer la nouvelle post-date AVANT d'appeler le pipeline pour éviter cette race condition. Ce faisant, on prend néanmoins le risque que si dans un plugin quelqu'un utilise $GLOBALS['meta']['date_prochain_postdate']
, on va lui casser son code...
Une dernière option qui ménage la chèvre et le choux serait de mettre un mutex sur calculer_prochain_postdate
. Si le mutex est pris par un thread, il ne peut pas l''être par un second et dans ce cas là on passe notre tour et on laisse le 1er thread finir son exécution.
Mais je ne connais pas vraiment ce qui se passe pour les autres pipeline, est ce vraiment un cas unique propre à celui-ci? Comment sont gérer ces cas là dans SPIP de manière générale?
Merci à vous.
cpol0