वार्षिक सालाना भुगतान करें और हर सशुल्क प्लान पर 2 महीने मुफ़्त पाएं। प्लान देखें
साइन इन करें मुफ़्त शुरू करें

खर्च पृष्ठ ज़्यादा दिखा रहा था, और एक पैसा भी नहीं हिला

सबसे पहले वह हिस्सा, जो बाकी पढ़ते हुए सबसे आसानी से छूट जाता है: कोई पैसा नहीं लिया गया। किसी वॉलेट से दो बार कटौती नहीं हुई, किसी कार्ड पर शुल्क नहीं लगा, और जो काम हुआ ही नहीं उस पर कोई सब्सक्रिप्शन भत्ता खर्च नहीं हु…

सबसे पहले वह हिस्सा, जो बाकी पढ़ते हुए सबसे आसानी से छूट जाता है: कोई पैसा नहीं लिया गया। किसी वॉलेट से दो बार कटौती नहीं हुई, किसी कार्ड पर शुल्क नहीं लगा, और जो काम हुआ ही नहीं उस पर कोई सब्सक्रिप्शन भत्ता खर्च नहीं हुआ।

जो टूटा वह स्क्रीन पर दिख रहा एक नंबर था। कुछ खातों में, आपके अपने खाता पृष्ठ पर उपयोग का विवरण ज़्यादा दिखा रहा था — हमने जो सबसे बुरा खाता मापा, उसमें उस बही से 2.4 गुना ज़्यादा जिसका उसे सारांश देना था। बही पूरे समय सही थी। मासिक सीमाएँ भी सही थीं, जो पूरी तरह किसी और जगह से पढ़ी जाती हैं। यह प्रदर्शन की खराबी थी, ठीक हो चुकी है, और इसका कारण यह रहा।

एक कुंजी जो ऐसी चीज़ ढूँढ़ रही थी जो किसी ने लिखी ही नहीं

आपके किसी काम से शुरू होने वाला काम — दैनिक उपयोग सारांश अपडेट करना, रेफ़रल क्रेडिट देना, कोई सूचना फैलाना — आपके अनुरोध के भीतर नहीं होता। अनुरोध एक संदेश लिखता है और पृष्ठभूमि का एक उपभोक्ता उसे पल भर बाद उठा लेता है; यही वह चीज़ है जो एक धीमे दुष्प्रभाव को तेज़ पृष्ठ धीमा करने से रोकती है।

इस व्यवस्था का ख़तरा यह है कि वही काम दो बार हो जाए, क्योंकि कोई भी ब्रोकर किसी अड़चन के बाद वही संदेश ख़ुशी-ख़ुशी दोबारा पहुँचा देता है। बचाव है एक इनबॉक्स: संसाधित करने से पहले उपभोक्ता उस संदेश की कुंजी वाली एक पंक्ति लिखकर संदेश पर दावा करता है, और एक यूनिक इंडेक्स दूसरा दावा असंभव बना देता है।

हमारा दावा एक जोड़े पर था — वह टेनेंट जिससे संदेश जुड़ा था, और संदेश कुंजी — और वह इस जोड़े को संदेश के लिफ़ाफ़े में मौजूद टेनेंट आईडी से मिलाकर ढूँढ़ता था, जो भरी हुई होती है।

दावा पंक्तियों में टेनेंट आईडी थी ही नहीं। हर एक खाली थी, और शुरू से ऐसी ही थी। एंटिटी का अपना दस्तावेज़ इन्हीं शब्दों में कहता था कि फ़्रेमवर्क इसे इन्सर्ट के समय मुहर लगा देता है। उसने कभी नहीं लगाई। जिस दिन हमने यह पकड़ा, उस दिन प्रोडक्शन पर मापा गया: इनबॉक्स की सभी 3,344 पंक्तियाँ खाली, जबकि उत्पादक पक्ष की 1,451 में से 1,174 पंक्तियों में असली टेनेंट मौजूद — और ठीक इसी वजह से किसी को पढ़ने वाले पक्ष पर शक नहीं हुआ।

तो खोज (टेनेंट, कुंजी) माँग रही थी, संग्रहीत पंक्ति (कुछ नहीं, कुंजी) थी, और मेल कभी हो ही नहीं सकता था।

कुछ भी विफल नहीं हुआ, इसीलिए यह हफ़्तों चलता रहा

ऐसी खोज जो कभी मेल खा ही नहीं सकती, सुनने में लगती है कि पहली ही कोशिश में त्रुटि देनी चाहिए। उसने उल्टा किया।

दावे ने तय किया कि संदेश नया है। फिर इन्सर्ट यूनिक इंडेक्स से टकराया और डुप्लिकेट कहकर अस्वीकार हुआ — सही ही, क्योंकि पंक्ति पहले से मौजूद थी। एक फ़ॉलबैक शाखा ने उस अस्वीकृति को पकड़ा और उदारता से पढ़ा: कोई और डिलीवरी इस पर दावा कर चुकी होगी, यहाँ करने को कुछ नहीं। लिफ़ाफ़ा "अभी संसाधित होना बाकी" स्थिति में रह गया, और चूँकि वह अभी बाकी था, अगली डिलीवरी ने उसे उठाया और काम दोबारा कर दिया।

हर उपभोक्ता अपना बकाया लगभग हर पैंतालीस सेकंड में, अनिश्चित काल तक दोबारा संसाधित कर रहा था। छब्बीस ऐसा कर रहे थे। एक प्रोडक्शन पंक्ति अपने आने के 333 घंटे बाद पूरी हुई, और उस अवधि के अधिकांश हिस्से में बार-बार पूरी होती रही थी।

असल में क्या टूटा

उन छब्बीस उपभोक्ताओं में से चार ओवरराइट करने के बजाय जोड़ते जाते हैं। वही चार बिलिंग प्रोजेक्शन हैं जिन्हें उपयोग पृष्ठ पढ़ता है, और यह बात वहीं सतह पर आई।

उनके पास ठीक इसी के ख़िलाफ़ एक स्पष्ट सुरक्षा थी, जो अगस्त की उस घटना के बाद लिखी गई थी जिसमें एक ही घटना एक गेज पर नौ बार लागू हो गई थी। यह सुरक्षा पंक्ति को संसाधित करने से पहले सफल चिह्नित करती है, ताकि दोबारा डिलीवरी उस चिह्न को पाकर रुक जाए। चिह्न हर बार सही लिखा जाता था। फिर अगला दावा उसी टूटी कुंजी से उसे ढूँढ़ता और पाता नहीं। यह गारंटी जिस दिन जारी हुई, उसी दिन से खोखली थी।

इसने जिन चीज़ों को छुआ नहीं, उन्हें ठीक-ठीक गिनाना ज़रूरी है, क्योंकि "बिलिंग प्रोजेक्शन" सुनने में चिंताजनक लगता है और तथ्य चिंताजनक नहीं हैं:

  • बही सही थी। हर एआई कॉल अपने मूल्य स्नैपशॉट के साथ ठीक एक बिलिंग रिकॉर्ड लिखती है, और इस रास्ते पर कुछ भी उन्हें नहीं लिखता।
  • कोई वॉलेट नहीं हिला। शेष राशि बही से आती है, किसी सारांश से कभी नहीं।
  • कोई सीमा नहीं हिली। बजट गार्ड एक अलग काउंटर पढ़ता है, और इस महीने आपने कितना खर्च किया इसका एकमात्र सत्य स्रोत वही है। किसी बढ़े हुए नंबर के कारण किसी को समय से पहले नहीं रोका गया, और जिसे नहीं गुज़रना चाहिए था वह गुज़रा भी नहीं।

प्रभावित सारांश को पढ़ने वाली एकमात्र चीज़ आपके अपने खाता पृष्ठ का उपयोग इतिहास है — आपका कुल और किस पर खर्च हुआ इसका विवरण। कुल प्रभाव क्षेत्र इतना ही है, और उसने बस ज़्यादा दिखाया।

वह आधा हिस्सा जिस पर कोई नहीं देख रहा था

यही टूटी खोज एक दूसरी जगह भी बैठी थी: वह रास्ता जो संदेश विफल होने पर चलता है। वहाँ वह उस पंक्ति को कभी नहीं ढूँढ़ पाती थी जिसे अपडेट करना था, और ठीक उसके नीचे "व्यवहार में अगम्य" टिप्पणी वाली एक शाखा थी — जो हर विफलता पर "यह विफलता अंतिम है" लौटाती थी।

तो पुनःप्रयास काउंटर कभी आगे नहीं बढ़ा और कोई ज़हरीला संदेश कभी डेड-लेटर कतार तक नहीं पहुँचा। त्रुटि-प्रबंधन की एक पूरी परत बंद पड़ी थी, ऐसी टिप्पणी के पीछे जो हर पढ़ने वाले से कहती थी कि यहाँ जाँचने को कुछ नहीं है।

समाधान

अब दोनों खोजें उपभोक्ता समूह के भीतर संदेश कुंजी पर चलती हैं, जो वैसे भी यूनिक इंडेक्स लागू करता है। संदेश कुंजियाँ उन्हें बनाने वाली चीज़ की आईडी से निकलती हैं, इसलिए संरचनात्मक रूप से टेनेंट के बीच टकरा ही नहीं सकतीं।

जिस दस्तावेज़ ने मुहर लगने का दावा किया था, उसे मिटाने के बजाय सुधारा गया। वही वाक्य जाल था, और उसे मिटाने से ऐसा कुछ नहीं बचता जो कहे कि आख़िरकार किसी ने जाँच की।

नौ परीक्षण इस व्यवहार को बाँधते हैं। उनमें से छह पुराने कोड पर विफल होते हैं, जिसकी पुष्टि हमने पुराना कोड वापस रखकर की।

बाद की सफ़ाई

बढ़ी हुई पंक्तियाँ ख़ुद ठीक हो जाती हैं। एक वर्कर हर घंटे, दो दिन की खिड़की में, दैनिक सारांश बही से दोबारा बनाता है। वह पूरे समय चल रहा था और हार रहा था: हर पैंतालीस सेकंड में दोबारा लागू करने वाले उपभोक्ता के सामने घंटे में एक बार चलना कोई निष्पक्ष दौड़ नहीं है।

अब जब उपभोक्ता दोबारा नहीं चलता, वर्कर जीतता है। उस खिड़की के भीतर बचे दो दिन, समाधान लाइव होते ही बही से दोबारा बना दिए गए। उससे पहले के दो दिन खिड़की से बाहर जा चुके थे, और उन पर जो बचा है वह हमारा अपना एक खाता और कहीं एक नगण्य अंतर है — इसलिए हमने उन्हें वैसे ही छोड़ दिया, बजाय इसके कि उनके पीछे जाने के लिए प्रोडक्शन में खिड़की चौड़ी करें; यह इशारा करने से बेहतर लगा कि सफ़ाई पूरी हो गई थी।

हमने इससे क्या सीखा

डीडुप्लिकेशन कुंजी को वही दर्शाना चाहिए जो इंडेक्स वास्तव में लागू करता है, न कि वह जो कोड मानता है कि लिखा गया था। इस कुंजी के दोनों आधे हिस्से अलग-अलग फ़ील्ड से भरे जा रहे थे, और किसी को भी कभी दूसरे के सामने मापा नहीं गया था। अब दोनों मापे जा चुके हैं, और यह साबित करने वाला परीक्षण उस संस्करण पर लाल हो जाता है जो ग़लत था।

शेयर करें LinkedIn X ईमेल
इसे अपने काम पर आज़माएँहर जवाब दिखाता है कि उसकी लागत कितनी रही। मुफ़्त प्लान से शुरू करें। मुफ़्त शुरू करें
प्रोडक्ट अपडेट पाएं, शोर नहीं नए मॉडल, फ़ीचर और changelog की मुख्य बातें - जब वाकई कुछ शिप हो, तभी एक छोटा ईमेल।
सदस्यता लेकर आप ToRun से उत्पाद अपडेट के ईमेल पाने के लिए सहमत होते हैं। आप कभी भी सदस्यता छोड़ सकते हैं। गोपनीयता नीति