
Τι Πραγματικά Χρειάζεται μια Έκδοση 2: 206 Commits από Ειλικρινείς Καταστάσεις
Το GeekBye v2 δεν ήταν μια κυκλοφορία με νέες λειτουργίες. Ήταν 206 commits στραμμένα σε μία ιδέα: η εφαρμογή δεν πρέπει ποτέ να λέει ψέματα για την ίδια της την κατάσταση. Να τι κοστίζει αυτό — μαζί με το λάθος μιας γραμμής στο lockfile που παραλίγο να μας εμποδίσει να κυκλοφορήσουμε οτιδήποτε από όλα αυτά.
Οι περισσότερες κυκλοφορίες «έκδοση 2» είναι ένας σωρός από νέες λειτουργίες με έναν μεγαλύτερο αριθμό πάνω τους. Το GeekBye v2 ήταν το αντίθετο. Δεν παρέδωσε σχεδόν καμία νέα ορατή στον χρήστη δυνατότητα. Τα 206 commits του ήταν στραμμένα σε μία, καθόλου εντυπωσιακή ιδέα:
Η εφαρμογή δεν πρέπει ποτέ να σου δείχνει μια κατάσταση που δεν είναι αληθινή.
Ακούγεται προφανές μέχρι να μετρήσεις με πόσους τρόπους μια desktop εφαρμογή λέει σιωπηλά ψέματα. Δείχνει ένα τικ σε ένα ανέβασμα που είναι ακόμα εν πτήσει. Λέει «συνδεδεμένο» πάνω σε ένα socket που πέθανε πριν από ένα λεπτό. Μένει σιωπηλή ενώ η μεταγραφή σου πετάγεται στο πάτωμα. Κανένα από αυτά δεν είναι crash. Είναι χειρότερα από crash, γιατί η εφαρμογή φαίνεται μια χαρά ενώ κάνει λάθος — και το μαθαίνεις μόνο αργότερα, όταν η εγγραφή που χρειαζόσουν δεν είναι εκεί.
Το v2 ήταν η κυκλοφορία όπου βγήκαμε κυνήγι για καθένα από αυτά τα μικρά ψέματα.
Το ψέμα που μισήσαμε περισσότερο: το ανέβασμα που «πέτυχε»
Το GeekBye μπορεί να κρατά αντίγραφα ασφαλείας των εγγραφών σου στο Google Drive. Στο v1, η σύνδεση στο Drive αντιμετωπιζόταν ως μια λεπτομέρεια στο παρασκήνιο — αν δούλευε, τέλεια· αν όχι, η αποτυχία ήταν ως επί το πλείστον αόρατη. Η εφαρμογή συνέχιζε να φαίνεται συνδεδεμένη. Υπέθετες ότι οι εγγραφές σου ήταν ασφαλείς. Μερικές φορές δεν ήταν.
Το v2 ξαναέχτισε αυτό γύρω από ειλικρινείς καταστάσεις σύνδεσης. Το Drive είναι τώρα πάντα σε μία από λίγες ρητές, αληθινές καταστάσεις — συνδεδεμένο, επανασυνδέεται, αποσυνδεδεμένο — και η εφαρμογή μεταδίδει κάθε αλλαγή αυτής της κατάστασης σε όλο το interface τη στιγμή που συμβαίνει. Όταν η σύνδεση είναι πεσμένη, ένα καθολικό banner επανασύνδεσης σου το λέει, παντού, ξεκάθαρα. Η εφαρμογή δεν προσποιείται πια ότι ένα ανέβασμα πέτυχε όταν δεν πέτυχε. Αν το αντίγραφο ασφαλείας σου δεν μπορεί να γίνει αυτή τη στιγμή, το μαθαίνεις αυτή τη στιγμή — όχι την επόμενη εβδομάδα, όταν πας να ψάξεις το αρχείο.
Από κάτω, αυτό είναι μια μικρή αρχιτεκτονική, όχι ένα σύνθημα: μία πηγή αλήθειας για τη σύνδεση, ένα συμβάν που απλώνεται σε κάθε τμήμα του UI όταν αλλάζει, και ένα banner που διαβάζει απευθείας από αυτή την κατάσταση. Δεν υπάρχει μονοπάτι όπου η σύνδεση είναι πεσμένη και το UI φαίνεται σηκωμένο, γιατί και τα δύο διαβάζουν από το ίδιο γεγονός.
Το ψέμα της χαμένης εγγραφής
Η δεύτερη μεγάλη διόρθωση ειλικρίνειας ήταν η ανάκτηση εγγραφών. Η μεταγραφή σε πραγματικό χρόνο χρειάζεται μια ζωντανή σύνδεση. Στο v1, αν αυτή η σύνδεση αναπηδούσε στη μέση μιας συνεδρίας — ένα τρεμόπαιγμα Wi-Fi, μια σήραγγα, μια επανασύνδεση VPN — ο ήχος κατά το κενό μπορούσε απλά να χαθεί. Η μεταγραφή είχε μια τρύπα μέσα της, και τίποτα δεν σου το έλεγε.
Το v2 άλλαξε το συμβόλαιο: ο ήχος διατηρείται τοπικά κατά ένα κενό σύνδεσης και συμφιλιώνεται μετά. Όταν ο σύνδεσμος πέφτει, το GeekBye κρατά τον ήχο ασφαλή στο μηχάνημά σου· όταν επανέρχεται, αυτός ο buffered ήχος στέλνεται και ράβεται στη μεταγραφή στη σωστή θέση. Τριάντα κακά δευτερόλεπτα δικτύου δεν σου κοστίζουν πια τριάντα δευτερόλεπτα σύσκεψης. Αυτό είναι το θεμέλιο πάνω στο οποίο έχτισαν απευθείας οι μεταγενέστερες κυκλοφορίες αξιοπιστίας — ο μηχανισμός επανασύνδεσης-και-buffering στο γιατί ο AI notetaker σου σταματά στο κακό Wi-Fi είναι η ίδια ιδέα, ενισχυμένη.
Το ψέμα της καταιγίδας αναδυόμενων παραθύρων
Υπάρχει μια πιο λεπτή ανειλικρίνεια στον τρόπο που οι εφαρμογές αναφέρουν προβλήματα: τα υπερ-αναφέρουν. Μια ασταθής στιγμή δικτύου μπορεί να πυροδοτήσει το ίδιο σφάλμα πέντε φορές, και ξαφνικά έχεις μια στοίβα από πανομοιότυπα κόκκινα toasts που θάβουν το ένα μήνυμα που έχει σημασία. Ούτε αυτό είναι ειλικρινές — είναι θόρυβος που προσποιείται ότι είναι πληροφορία.
Έτσι το v2 πρόσθεσε περιορισμό toasts ανά κατηγορία και δρομολόγηση σφαλμάτων. Τα σφάλματα ομαδοποιούνται με βάση το τι πραγματικά είναι, και κάθε κατηγορία περιορίζεται σε ρυθμό, ώστε ένα μεμονωμένο υποκείμενο πρόβλημα να παράγει ένα ξεκάθαρο μήνυμα, όχι μια μπαράζ. Ένα ζήτημα rate-limit δρομολογείται σε ένα μήνυμα rate-limit· ένα ζήτημα σύνδεσης δρομολογείται σε ένα μήνυμα σύνδεσης. Η εφαρμογή σου λέει τι είναι αληθινό, μία φορά — η ίδια πειθαρχία που αργότερα εμπόδισε ένα 429 να μεταμφιεστεί σε αποσύνδεση στο η μέρα που η εφαρμογή μας έκανε DDoS στον εαυτό της.
Ο αριθμός 206 είναι το ζητούμενο
Ειλικρινείς καταστάσεις, banner επανασύνδεσης, ανάκτηση εγγραφών, δρομολόγηση toasts — αυτές είναι τέσσερις ιδέες. Η κυκλοφορία ήταν 206 commits. Πού πήγαν τα υπόλοιπα;
Στη μη εντυπωσιακή μακριά ουρά που το «μην δείχνεις ποτέ μια ψεύτικη κατάσταση» πραγματικά απαιτεί. Κάθε σημείο όπου το παλιό UI μπορούσε να βγει εκτός συγχρονισμού με την πραγματικότητα έπρεπε να βρεθεί και να ξανακαλωδιωθεί ώστε να διαβάζει από την αλήθεια αντί από ένα παλιό αντίγραφο. Κάθε μονοπάτι επανασύνδεσης έπρεπε να φτιαχτεί ώστε να ενημερώνει την κοινή κατάσταση αντί να μαντεύει τοπικά. Δεκάδες μικρές διορθώσεις αξιοπιστίας στην εγγραφή, τη μεταγραφή και τα ανεβάσματα — καθεμία κλείνοντας ένα συγκεκριμένο κενό όπου η εφαρμογή μπορούσε να φαίνεται σωστή ενώ έκανε λάθος.
Αυτό κοστίζει μια πραγματική «έκδοση 2» όταν ο στόχος είναι εμπιστοσύνη αντί για λειτουργίες. Δεν υπάρχει ένα μοναδικό commit-τίτλος. Υπάρχουν 206 μικρά, και η κυκλοφορία μόνο νιώθεται σαν ένα πράγμα — ηρεμία — επειδή και τα 206 τραβούν προς την ίδια κατεύθυνση.
Η κυκλοφορία παραλίγο να μην βγει
Να η ιστορία πολέμου, και είναι καλή, γιατί αφορά το πώς η δική μας εφαρμογή είπε ψέματα σ' εμάς.
Όταν κόβεις μια κυκλοφορία, ένα script αναβάθμισης έκδοσης σφραγίζει τον νέο αριθμό σε όλο το project. Στο v2.0.0 ενημέρωσε την έκδοση της εφαρμογής — αλλά το package-lock.json, το ακριβές κατάστιχο εξαρτήσεων του npm, έμεινε να δείχνει στην παλιά έκδοση, 1.9.0. Τοπικά, όλα ήταν εντάξει· κανείς δεν ξαναεγκαθιστά εξαρτήσεις μόνο και μόνο για να κάνει build. Αλλά το CI τρέχει npm ci, και όλη η δουλειά του npm ci είναι να αρνηθεί να προχωρήσει αν το lockfile διαφωνεί με το manifest. Είναι μια λειτουργία αυστηρότητας — και έκανε ακριβώς αυτό που έπρεπε, αποτυγχάνοντας το build για τη μεγαλύτερη κυκλοφορία που είχαμε ποτέ κόψει.
Μετά αναδύθηκε από κάτω μια δεύτερη, πιο πονηρή. Ένα νεότερο npm είχε κλαδέψει μια προαιρετική μεταβατική εξάρτηση — το πακέτο encoding που τραβά μαζί του το node-fetch — από το lockfile ως περιττή. Μόνο που η καθαρή εγκατάσταση του CI μας όντως τη χρειαζόταν, οπότε η εγκατάσταση έσπασε με τρόπο που δεν είχε καμία σχέση με τον κώδικά μας και κάθε σχέση με το ότι το κατάστιχο ήταν διακριτικά λάθος.
Και οι δύο ήταν διορθώσεις μιας γραμμής: επανασυγχρόνισε το lockfile στην πραγματική έκδοση, επανάφερε την κλαδεμένη καταχώρηση. Και οι δύο είναι επίσης τέλεια, ταπεινωτικά παραδείγματα ακριβώς αυτού που αφορούσε το v2 — μια κατάσταση που ισχυριζόταν ότι είναι αληθινή και δεν ήταν. Το lockfile υποτίθεται ότι είναι το ειλικρινές αρχείο του τι εξαρτάται η εφαρμογή. Όταν παρέκκλινε από την πραγματικότητα, το build έκανε ακριβώς αυτό που κάνει τώρα η εφαρμογή μας για τους χρήστες: αρνήθηκε να προσποιηθεί ότι όλα ήταν εντάξει. Αποδεικνύεται ότι το να παραδίδεις μια κυκλοφορία αξιοπιστίας είναι πρόβλημα αξιοπιστίας μέχρι κάτω.
Τρία πράγματα που μας δίδαξε το v2
- Οι επικίνδυνες αποτυχίες είναι οι σιωπηλές. Ένα crash ανακοινώνει τον εαυτό του. Ένα ψεύτικο «συνδεδεμένο», ένα φανταστικό επιτυχημένο ανέβασμα, μια μεταγραφή με μια αόρατη τρύπα — αυτά σου κοστίζουν εμπιστοσύνη ακριβώς επειδή τίποτα δεν φαίνεται λάθος. Κυνήγα τα σιωπηλά ψέματα.
- Η ειλικρίνεια είναι αρχιτεκτονική, όχι μήνυμα. Δεν μπορείς να βιδώσεις το «λέγε την αλήθεια» πάνω σε ένα UI σαν banner. Το banner πρέπει να διαβάζει από την ίδια μοναδική πηγή αλήθειας με όλα τα άλλα, αλλιώς γίνεται άλλο ένα πράγμα που μπορεί να είναι λάθος. Ένα γεγονός, απλωμένο — ποτέ δύο αντίγραφα που μπορούν να διαφωνήσουν.
- Μια έκδοση 2 άξια του αριθμού είναι κυρίως αόρατη. Αν το v2 σου είναι μια λίστα λειτουργιών, είναι ένα v1.5 με μάρκετινγκ. Ένα πραγματικό v2 είναι 206 commits που κανείς δεν μπορεί να δείξει ξεχωριστά, αθροιζόμενα σε ένα προϊόν που απλά σταματά να σου λέει ψέματα.
Το GeekBye v2.0.0 είναι το θεμέλιο πάνω στο οποίο έχτισε κάθε κυκλοφορία από τότε. Για το τι κουβαλά αυτό το θεμέλιο, δες γιατί ο AI notetaker σου σταματά στο κακό Wi-Fi, η μέρα που η εφαρμογή μας έκανε DDoS στον εαυτό της (v2.0.1) και μεταγραφή σε πραγματικό χρόνο όταν το firewall μπλοκάρει τα WebSockets (v2.0.8). Για την ηρεμία στην υπηρεσία της οποίας ήταν όλα, τι νέο υπάρχει στο GeekBye v2.