Résumé
score_to_hide_post peut être ramené à 0 car le job d’arrière-plan Jobs::ReviewablePriorities écrit priority_#{priorities[:high]} comme 0 lorsque la requête de percentile ne renvoie aucune ligne. Le job est déclenché lorsque reviewable_count >= 15, mais le calcul du percentile n’inclut que les éléments révisables qui satisfont HAVING COUNT(*) >= :target_count (où target_count est généralement 2). Si la plupart des éléments révisables n’ont qu’un seul drapeau, la sous-requête de percentile ne renvoie rien → high devient 0 → score_to_hide_post = ((high * ratio) * scale).truncate(2) est évalué à 0. Cela fait s’effondrer le seuil de masquage à zéro et produit un comportement de masquage incorrect.
Origine (code / faits pertinents)
score_to_hide_postest calculé via :
score_to_hide_post = ((high.to_f * ratio) * scale).truncate(2)
highest lu à partir du magasin de plugins :
PluginStore.get("reviewables", "priority_#{priorities[:high]}")
- Cette entrée du magasin de plugins est écrite par
Jobs::ReviewablePriorities(le job système).
Le job s’exécute lorsque :
reviewable_count = Reviewable.approved.where("score > ?", min_priority_threshold).count
return if reviewable_count < self.class.min_reviewables
où self.class.min_reviewables est 15.
- Le job calcule
highen utilisant SQL :
SELECT COALESCE(PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY score), 0.0) AS medium,
COALESCE(PERCENTILE_DISC(0.85) WITHIN GROUP (ORDER BY score), 0.0) AS high
FROM (
SELECT r.score
FROM reviewables AS r
INNER JOIN reviewable_scores AS rs ON rs.reviewable_id = r.id
WHERE r.score > :min_priority AND r.status = 1
GROUP BY r.id
HAVING COUNT(*) >= :target_count
) AS x
avec :target_count généralement 2.
Cause racine
Il existe deux seuils distincts qui créent ensemble un écart :
- Le job est déclenché lorsqu’il y a au moins
min_reviewables(15) éléments révisables supérieurs àmin_priority_threshold— il s’agit d’un décompte grossier ignorant l’exigence de:target_count. - Mais le calcul du percentile qui produit
highn’inclut que les éléments révisables qui satisfontCOUNT(*) >= :target_count(c’est-à-dire au moins2reviewable_scores). Si de nombreux éléments révisables n’ont chacun qu’un seul drapeau, la sous-requête ne renvoie aucune ligne et le percentile renvoie la valeur de repli0.0.
Ainsi, le job peut s’exécuter (car il y a ≥ 15 éléments révisables selon le décompte grossier) mais l’agrégation du percentile n’a pas de lignes qualifiées (car aucune ne satisfait le HAVING), provoquant high à 0 et ensuite priority_high à être écrit comme 0. Cela alimente score_to_hide_post et le fait s’effondrer.
Impact
score_to_hide_postdevient0, ce qui peut à tort considérer des publications comme masquées ou autrement casser la logique qui dépend d’un seuil de masquage raisonnable.- Cela se produit sur les sites où il existe de nombreux éléments révisables mais chacun n’a qu’un seul drapeau/réviseur, ce qui n’est pas rare dans les communautés petites/moyennes.
Corrections suggérées (options)
- S’assurer que la requête de percentile renvoie suffisamment de lignes avant d’écrire
- Après avoir exécuté la requête de percentile, vérifiez si la valeur du percentile est
0et si la sous-requête a renvoyé des lignes.
Si aucune ligne n’a été renvoyée, ne pas écraser lepriority_highexistant ; au lieu de cela, ignorer l’écriture, conserver la valeur précédente ou revenir à une valeur par défaut configurée. - C’est l’approche la plus sûre et la moins invasive.
- Ajuster le déclenchement du job pour tenir compte de
target_count
- Modifier la pré-vérification du job afin qu’elle ne s’exécute que lorsque le nombre d’éléments révisables satisfaisant
HAVING COUNT(*) >= :target_countest d’au moinsmin_reviewables.
En d’autres termes, compter les éléments révisables regroupés paridqui satisfontCOUNT(*) >= target_countet ne procéder que si ce décompte est ≥min_reviewables.
- Permettre aux administrateurs de définir manuellement
score_to_hide_postoupriority_high
- Fournir une option dans l’interface d’administration pour saisir ou ajuster directement
score_to_hide_postoupriority_high. - De cette façon, même si la requête de percentile produit des résultats inattendus (par exemple, en raison d’un échantillon trop faible), le système peut utiliser un seuil raisonnable spécifié par l’administrateur, évitant ainsi les erreurs causées par les calculs automatiques.