Bugg: olästräknaren för PM fastnar permanent när ett oläst PM flyttas till egen mapp
Det här kräver ingen illvilja för att uppstå. Det räcker att man använder mappar, vilket gör att antalet drabbade konton växer av sig självt över tid.
Reproduktion- Skicka ett PM till dig själv, bocka ur att spara i "Skickat".
- Skapa en ny mapp.
- Flytta PM:et till mappen, fortfarande oläst.
- Öppna PM:et i mappen.
Räknaren står nu kvar och går inte ner. Den överlever utloggning, webbläsarbyte och radering av själva meddelandet.
Manuell fix, och vad den avslöjar
Flytta tillbaka PM:et till inkorgen, markera som oläst, öppna det.
Att steget "markera som oläst" behövs är det intressanta. Vore raden fortfarande oläst hade steget varit meningslöst. Alltså står raden på läst medan räknaren står på ett eller fler. Rad och räknare har divergerat, och räknaren är lagrad, inte härledd. Dekrementeringen ligger rimligtvis i inkorgsvyn i stället för i själva övergången oläst till läst, så den körs aldrig när meddelandet öppnas i en egen mapp.
Varför det inte bara är kosmetiskt
Ett konto med fantomflagga faller sannolikt ur den billiga vägen på notis-endpointen. I stället för att servera ett cachat noll-svar går varje poll ner i en riktig slagning mot PM-tabellen, som returnerar noll rader. Notis-pollen är typiskt sajtens mest frekventa anrop, så varje sådant konto kostar mätbart mer per request än ett friskt. Med tanke på belastningen mot cache-lagret på sistone är det den delen jag tror är värd att titta på först.
Verifiera själva
En query ger er storleken på problemet direkt, i stället för att behöva lita på mig:
Kod:
SELECT COUNT(*) FROM user u
WHERE u.pm_unread <> (
SELECT COUNT(*) FROM pm
WHERE pm.recipient_id = u.id
AND pm.unread = 1
AND pm.deleted = 0
);
Kolumn- och tabellnamn är gissningar, men principen är antalet konton där lagrad räknare inte matchar verkligheten. Värt att kontrollera samtidigt: skriver notis-endpointen tillbaka ett korrigerat värde när den ser divergensen? I så fall har en läsning blivit en skrivning på den hetaste vägen ni har.
Förslag på åtgärd- Underhåll räknaren transaktionellt i varje övergång: insert, läs, markera oläst, flytt, radering, massradering, mappradering. Aldrig i vylagret. Den heta vägen ska inte röra PM-tabellen alls.
- Reconciliation som offline batchjobb. Inte vid inloggning, för då blir en inloggningsstorm en reconcile-storm.
- Test som invariant: efter varje övergång ska lagrad räknare vara lika med härledd.
- Härledd COUNT som reparations- och felsökningsverktyg, inte som produktionsläsväg. Att lägga den queryn på notis-endpointen vore att bygga in precis den last man vill undvika.
Separat observation
Loopen ovan består av fyra till fem autentiserade skrivningar per varv och verkar inte vara strypt. Det är ett eget problem, oberoende av den här buggen, och relevant givet att forumet har haft problem med parallellkonton tidigare. En rate limit på skapande av PM och mappoperationer vore rimlig även för äldre konton. Den befintliga per-dygn-spärren verkar inte gälla alla.
Jag rapporterade något liknande via PM för ungefär ett halvår sedan från ett annat konto, utan svar. Lägger upp det öppet den här gången så att det åtminstone går att verifiera av fler.