요약
score_to_hide_post가 0으로 떨어질 수 있습니다. 이는 백그라운드 작업인 Jobs::ReviewablePriorities가 백분위수 쿼리가 행을 반환하지 않을 때 priority_#{priorities[:high]}를 0으로 쓰기 때문입니다. 이 작업은 reviewable_count >= 15일 때 트리거되지만, 백분위수 계산에는 HAVING COUNT(*) >= :target_count(여기서 target_count는 일반적으로 2) 조건을 충족하는 reviewable만 포함됩니다. 대부분의 reviewable이 하나의 플래그만 가지고 있다면, 백분위수 서브쿼리는 아무것도 반환하지 않아 → high가 0이 되고 → score_to_hide_post = ((high * ratio) * scale).truncate(2)가 0으로 계산됩니다. 이로 인해 숨김 기준선이 0으로 붕괴되어 잘못된 숨김 동작이 발생합니다.
출처 (관련 코드/사실)
score_to_hide_post는 다음을 통해 계산됩니다:
score_to_hide_post = ((high.to_f * ratio) * scale).truncate(2)
high는 플러그인 스토어에서 읽힙니다:
PluginStore.get("reviewables", "priority_#{priorities[:high]}")
- 해당 플러그인 스토어 항목은 시스템 작업인
Jobs::ReviewablePriorities에 의해 기록됩니다.
이 작업은 다음 조건에서 실행됩니다:
reviewable_count = Reviewable.approved.where("score > ?", min_priority_threshold).count
return if reviewable_count < self.class.min_reviewables
여기서 self.class.min_reviewables은 15입니다.
- 이 작업은 SQL을 사용하여
high를 계산합니다:
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
여기서 :target_count는 일반적으로 2입니다.
근본 원인
함께 갭을 생성하는 두 개의 서로 다른 임계값이 있습니다:
- 작업은
min_priority_threshold를 초과하는 reviewable이 최소min_reviewables(15)개 이상일 때 트리거됩니다 — 이는:target_count요구 사항을 무시한 거친 카운트입니다. - 그러나
high를 생성하는 백분위수 계산에는COUNT(*) >= :target_count(즉, 최소2개의 reviewable_scores)를 가진 reviewable만 포함됩니다. 많은 reviewable이 각각 플래그가 하나씩만 있다면, 서브쿼리는 행을 반환하지 않고 백분위수는 폴백 값인0.0을 반환합니다.
따라서 작업은 실행될 수 있습니다(거친 카운트 기준 reviewable이 15개 이상이기 때문에) 하지만 백분위수 집계에는 자격을 갖춘 행이 없습니다(HAVING 조건을 충족하는 것이 없기 때문에), 이로 인해 high가 0이 되고 priority_high가 0으로 기록됩니다. 이것이 score_to_hide_post에 전달되어 값을 붕괴시킵니다.
영향
score_to_hide_post가0이 되면, 게시물이 잘못 숨겨진 것으로 간주되거나 합리적인 숨김 기준선에 의존하는 로직이 깨질 수 있습니다.- 이는 많은 reviewable이 존재하지만 각각 단일 플래그/리뷰어만 가진 사이트에서 발생하며, 이는 중소규모 커뮤니티에서 드문 일이 아닙니다.
권장 수정 사항 (옵션)
- 기록하기 전에 백분위수 쿼리가 충분한 행을 반환하도록 보장
- 백분위수 쿼리를 실행한 후, 백분위수 값이
0인지 및 서브쿼리가 행을 반환했는지를 확인합니다.
행이 반환되지 않았다면, 기존priority_high를 덮어쓰지 말고 대신 기록을 건너뛰거나 이전 값을 유지하거나 구성된 기본값으로 폴백합니다. - 이것이 가장 안전하고 침습적이지 않은 접근 방식입니다.
target_count를 고려하여 작업 트리거 조정
- 작업 사전 확인을 수정하여,
HAVING COUNT(*) >= :target_count를 충족하는 reviewable의 수가 최소min_reviewables이상일 때만 실행되도록 합니다.
즉,COUNT(*) >= target_count를 만족하는id별 그룹화된 reviewable을 카운트하고, 해당 수가min_reviewables이상일 때만 진행합니다.
- 관리자가
score_to_hide_post또는priority_high를 수동으로 설정할 수 있도록 허용
- 관리자 인터페이스에서
score_to_hide_post또는priority_high를 직접 입력하거나 조정할 수 있는 옵션을 제공합니다. - 이렇게 하면 백분위수 쿼리가 예상치 못한 결과를 생성하더라도(예: 샘플이 너무 적을 경우), 시스템이 관리자가 지정한 합리적인 기준선을 사용하여 자동 계산으로 인한 오류를 방지할 수 있습니다.