Τι αγγίζει πραγματικά η διαγραφή ενός μετρητή
Η διαγραφή ενός μετρητή εδώ αδειάζει 33 πίνακες. Χθες άδειαζε 25.
Οι οκτώ που παρέλειπε είχαν δημιουργηθεί όλοι την προηγούμενη μέρα, μεταξύ 11:10 το πρωί και 15:10 το απόγευμα.
Πώς λειτουργεί η διαγραφή
Ο κάτοχος ενός μετρητή μπορεί να τον διαγράψει. Χρειάζεται ένα αίτημα POST, το token του κατόχου και τον αριθμό του μετρητή πληκτρολογημένο με το χέρι, επειδή δεν υπάρχει αναίρεση. Τίποτα δεν κρατιέται στην άκρη: ένα σκιώδες αντίγραφο θα ήταν το αντίθετο από αυτό που ζητήθηκε, και οι σύνδεσμοι εξαγωγής βρίσκονται πάνω από το κουμπί για όποιον θέλει αντίγραφο.
Έπειτα αδειάζει μια λίστα πινάκων σε μία μόνο συναλλαγή, με τον κύριο πίνακα τελευταίο, και μια «ταφόπλακα» καταχωρίζεται στο αρχείο, ώστε ο αριθμός να μην μπορεί ποτέ να δοθεί σε κάποιον άλλο. Αν αποτύχει οποιοδήποτε μέρος, ολόκληρη η διαδικασία αναιρείται. Καλύτερα τίποτα διαγραμμένο παρά μισοδιαγραμμένο.
Πάνω από αυτή τη λίστα, στον πηγαίο κώδικα, βρίσκεται το εξής σχόλιο:
«Κάθε πίνακας που γνωρίζει κάτι για αυτόν τον μετρητή. Ως λίστα και όχι σκορπισμένοι μέσα στον κώδικα: ό,τι λείπει εδώ μένει πίσω ως ορφανή γραμμή, και κανείς δεν το προσέχει.»
Το σχόλιο περιέγραψε το κενό μία μέρα πριν αυτό ανοίξει
Χθες εμφανίστηκαν έξι νέοι πίνακες για μια νέα λειτουργία — χρόνος στη σελίδα, βάθος κύλισης, σελίδες εξόδου — μαζί με δύο ακόμη. Μεταξύ 11:10 και 15:10.
Η λίστα διαγραφής είχε τροποποιηθεί την ίδια μέρα, για να προστεθεί ένας άλλος νέος πίνακας. Οι οκτώ ήρθαν μετά από αυτό, και η λίστα δεν άλλαξε ξανά. Έτσι, για ένα απόγευμα, η διαγραφή ενός μετρητή άφηνε πίσω 4.840 γραμμές δεδομένων συμπεριφοράς, μοιρασμένες σε οκτώ πίνακες. Το κενό εντοπίστηκε την επόμενη μέρα και έκλεισε· αυτό που αποκάλυψε είναι ότι η λίστα χρειαζόταν κάτι άλλο εκτός από τη μνήμη για να μένει πλήρης.
Αυτή δεν είναι μια ιστορία απροσεξίας. Κάποιος έγραψε τη λίστα, κατάλαβε ακριβώς γιατί ήταν λίστα, κατέγραψε τι συμβαίνει όταν μένει πίσω, και την ενημέρωσε εκείνη ακριβώς τη μέρα για έναν πίνακα. Και παρ' όλα αυτά έμεινε πίσω, γιατί το να κρατάς δύο πράγματα συγχρονισμένα απλώς θυμούμενος να το κάνεις είναι κάτι που οι άνθρωποι κάνουν αξιόπιστα μέχρι εκείνο το απόγευμα που δεν το κάνουν.
Η διόρθωση, και η άλλη διόρθωση
Τα οκτώ ονόματα βρίσκονται τώρα στη λίστα. Μπήκαν στις αλφαβητικές τους θέσεις αντί να προστεθούν στο τέλος, επειδή σε μια ταξινομημένη λίστα ένα κενό φαίνεται, ενώ σε μια λίστα που απλώς μεγαλώνει προς το τέλος δεν φαίνεται.
Αυτή είναι η μικρή διόρθωση. Αυτή που μετράει είναι ένα script που ρωτά τη βάση δεδομένων ποιοι πίνακες περιέχουν αριθμό μετρητή, διαβάζει τη λίστα από το αρχείο πηγαίου κώδικα αντί να την επαναλαμβάνει, και συγκρίνει. Όποιος προσθέτει πίνακα το εκτελεί μία φορά. Δεν μπορεί να ξεχαστεί όπως ξεχνιέται μια λίστα, επειδή δεν αποθηκεύει τίποτα — παράγει την απάντηση από το σχήμα της βάσης κάθε φορά.
Στην πρώτη του εκτέλεση βρήκε και κάτι άλλο: 25 γραμμές σε οκτώ ακόμη πίνακες, των οποίων ο αριθμός μετρητή δεν υπάρχει ούτε στον ενεργό πίνακα ούτε στο αρχείο. Όχι διαγραμμένοι μετρητές — αυτοί αφήνουν ταφόπλακα. Αριθμοί που δεν ανήκουν σε τίποτα απολύτως, οι περισσότεροι προφανείς αριθμοί δοκιμών από την εποχή πριν υπάρξει ο έλεγχος στο αρχείο. Καταγράφηκαν σε ένα αρχείο έξω από τον ριζικό κατάλογο του ιστότοπου και έπειτα αφαιρέθηκαν.
Τι γενικεύεται από αυτό
Κάθε λίστα που πρέπει να μένει συγχρονισμένη με κάτι άλλο κάποια στιγμή θα πάψει να είναι, και το κενό θα είναι αόρατο, επειδή μια λίστα από την οποία λείπει μια εγγραφή μοιάζει ακριβώς με μια λίστα που είναι πλήρης.
Η άμυνα δεν είναι η πειθαρχία. Είναι να παράγεται η μία πλευρά από την άλλη και να ελέγχεται ότι συμφωνούν — και ο έλεγχος αυτός να τρέχει τη στιγμή που κάποιος προσθέτει το νέο στοιχείο, όχι τη στιγμή που κάποιος αναρωτιέται.
Το σχόλιο πάνω από τη λίστα είχε δίκιο σε όλα εκτός από μία λέξη. Έλεγε ότι κανείς δεν το προσέχει. Κάποιος το πρόσεξε, μία μέρα αργότερα, επειδή έψαξε με ένα script αντί για τη μνήμη του.