जब फ़ोन सो जाए तब भी चैट चालू रखना
Mythex का एजेंट एक अनुरोध पर मिनटों तक काम कर सकता है, और आप शायद फ़ोन से देख रहे हों, जो काम के दौरान लॉक होता है, ऐप बदलता है और network बदलता है। दो bugs इसमें गड़बड़ करते थे। एक में चैट हर "पेज फिर से दिख रहा है" संकेत को इस बात का सबूत मानती थी कि उसका कनेक्शन मर गया, और वह "Connecting…" पर अटककर लूप में चलती थी। दूसरे में, जो फ़ोन नई चैट के पहले जवाब के दौरान सोता रहा, वह लौटने पर जवाब के सिर्फ़ शुरुआती कुछ टुकड़े दिखाता था, जब तक आप मैन्युअल रीफ़्रेश न करें। दोनों ठीक हो गए हैं।
चैट चलते टर्न को कैसे फ़ॉलो करती है
एजेंट के काम करते समय चैट हमारे सर्वर से एक stream खुली रखती है: हर कदम, यानी एक विचार, एक tool call, जवाब का एक टुकड़ा, एक event के रूप में आता है। अगर stream टूटे, तो चैट फिर से कनेक्ट होती है, और सर्वर हाल के events को एक buffer से दोबारा भेजता है, जो पिछले 120 सेकंड रखता है। टर्न खत्म होने पर चैट सर्वर से सेव किया हुआ इतिहास भी माँगती है, और जो उसने दिखाया था उसका मिलान सेव किए गए से करती है। यह आखिरी कदम वह पकड़ता है जो stream से छूट गया।
जब कुछ न हो रहा हो, तब जीवित और मरे कनेक्शन में फ़र्क करने के लिए सर्वर हर 15 सेकंड में एक छोटा "ping" भेजता है।
Bug 1: जागने से एक स्वस्थ stream मर गई
ब्राउज़र पेज को बताता है जब वह फिर दिखने लगे: tab बदलने के बाद, स्क्रीन अनलॉक होने के बाद। हम इसे कनेक्शन जाँचने का संकेत मानते थे, और व्यवहार में stream को रद्द करके दोबारा कनेक्ट करते थे, यह मानकर कि वह छिपे रहते हुए मर गई।
फ़ोन और embedded browsers में ये events stream मरने से कहीं ज़्यादा बार चलते हैं: हर tab बदलने पर, हर अनलॉक पर, और कुछ embedded browsers में हर दो सेकंड जैसे। हर एक एक पूरी तरह स्वस्थ stream को रद्द करता था। चैट फिर से कनेक्ट होती, replay होता, फिर रद्द हो जाता, और अंत में "Connecting…" पर अटक जाती। फिर वह कहती कि टर्न खत्म हो गया, जबकि एजेंट अब भी काम कर रहा था।
समाधान: stream को इस आधार पर परखें कि वह बोल रही है या नहीं
अब चैट हर project की stream का आखिरी संकेत रिकॉर्ड करती है, जो events और 15-सेकंड वाले pings दोनों हैं। "फिर से दिख रहा है" संकेत सिर्फ़ उस stream को रद्द करता है जो 25 सेकंड से चुप है: ping अंतराल और धीमे network hop के जोड़ से भी ज़्यादा, इसलिए जीवित stream कभी इसमें नहीं आती। Tests जाँचते हैं कि ping जीवन का संकेत गिना जाता है, और जो stream अभी-अभी ping कर चुकी है उसे मरा नहीं माना जाता।
इससे निकला नियम: पेज की दृश्यता पेज के बारे में बताती है, नेटवर्क कनेक्शन के बारे में नहीं। कनेक्शन से ही पूछो।
Bug 2: फ़ोन जागने के बाद आधा जवाब
यह हम iOS simulator में हर बार दोहरा सकते थे:
- एक नई चैट शुरू करें और ऐसा अनुरोध भेजें जिसमें समय लगे।
- फ़ोन को build के दौरान सोने दें।
- टर्न खत्म होने और दो-मिनट वाला replay buffer खत्म होने के बाद लौटें।
चैट जवाब के पहले कुछ blocks दिखाती थी, जिन्हें खत्म हुआ चिह्नित किया गया था, और रीफ़्रेश तक वैसी ही रहती थी।
क्यों
नई चैट में तब तक thread नहीं होता, यानी सेव की गई बातचीत, जब तक पहला message उसे नहीं बनाता। यह send function के भीतर होता है, उसके बाद जब send पहले ही reconcile step पकड़ चुका था, जो अब भी मानता था कि thread नहीं है। तो नई चैट में पहले टर्न के अंत में reconcile ने कोई thread नहीं देखा, और बिना कुछ मांगे चुपचाप लौट गया।
आम तौर पर किसी ने ध्यान नहीं दिया, क्योंकि stream ने पूरा टर्न वैसे भी दे दिया था। लेकिन जो फ़ोन टर्न के दौरान सोया रहा और 120 सेकंड का replay buffer खत्म होने के बाद लौटा, वह stream से छूटे events नहीं ले सकता था। और जो reconcile उस अंतर को भरता, वह कभी चला ही नहीं था।
समाधान
- Send reconcile को बताता है कि टर्न किस thread का है, ताकि नई चैट के पहले टर्न को भी बाकी टर्न की तरह मिलाया जाए। अगर जवाब आने तक आप कोई दूसरी चैट खोल चुके हैं, तो नतीजा गिराया जाता है, न कि गलत जगह दिखाया जाता है।
- विफल reconcile को दोबारा कोशिश की जाती है। खराब कनेक्शन पर जागता फ़ोन पा सकता है कि टर्न खत्म हो चुका, और फिर उसे लाने में विफल हो। अब यह याद रखा जाता है, और tab फिर दिखने पर या network लौटने पर चैट फिर पूछती है।
- "Worked for" ईमानदार है। हर जवाब दिखाता है कि एजेंट ने कितनी देर काम किया। अगर tab ने सर्वर का टर्न-समाप्ति संदेश कभी नहीं देखा, तो वह उसे अपनी घड़ी से भर देता था, जो Send से लेकर फ़ोन जागने तक चलती थी, यानी दूर बिताया समय भी उसमें जुड़ जाता था। अब वह आँकड़ा अनुमान के रूप में चिह्नित है, और इतिहास आने पर सेव की गई अवधि से बदल जाता है।
हमने क्या सीखा
- उसी उपकरण और उसी तरीके से परखें जैसे लोग उसे इस्तेमाल करते हैं। दोनों bugs "काम करती stream" और "जेब में पड़े फ़ोन" के बीच की जगह में रहते थे।
- जो fallback कभी नहीं चलता, वह fallback नहीं है। reconcile step ठीक इसी स्थिति को पकड़ने के लिए था, और चुपचाप छोड़ दिया जाता था।
- वसूली को भी दोबारा कोशिश दें। जिस पल फ़ोन जागता है, अक्सर उसका कनेक्शन सबसे खराब होता है।
- अनुमान को तथ्य बनाकर न दिखाएँ। गलत घड़ी से निकली अवधि कुछ न होने से भी बुरी है; उसे चिह्नित करें या बदल दें।
इसी काम ने उस दौरान दिखने वाली कुछ और चीज़ें भी सुधारीं: shell कदम अब cd के बजाय उस command से लेबल होते हैं जो असली काम करता है, चैट के screenshots पेज के ऊपर-बाएँ भाग को रखते हैं और कॉलम में फ़िट होते हैं, और नया प्रोजेक्ट बिना रीफ़्रेश के अपना बना हुआ नाम ले लेता है।
अगर आप फ़ोन के लिए अपना ऐप बना रहे हैं, तो मोबाइल-फ़्रेंडली वेब ऐप कैसे बनाएँ और native बनाम progressive web apps की गाइड बुनियादी बातें कवर करती हैं। चैट के बारे में और chat docs में है।