प्रॉम्प्ट और लागू होने वाले परिदृश्य
एक टास्क एडिटर सबमिट किए गए शीर्षक को तुरंत प्रदर्शित करता है। कोई यूज़र किसी भी अनुरोध के पूरा होने से पहले शीर्षक A और फिर शीर्षक B सबमिट कर सकता है। दूसरा रिस्पॉन्स पहले आ सकता है, कोई भी अनुरोध विफल हो सकता है, दोनों के पेंडिंग रहने के दौरान एक बैकग्राउंड रीफ़ेच पूरा हो सकता है, और कोई अन्य यूज़र उसी टास्क को अपडेट कर सकता है। सर्वर हर स्वीकृत राइट के बाद विहित (canonical) टास्क और एक मोनोटोनिक रूप से बढ़ता हुआ रिसोर्स वर्ज़न लौटाता है।
क्लाइंट स्टेट, रिक्वेस्ट अनुबंध, ऑर्डरिंग नीति, विफलता रिकवरी, कॉन्फ्लिक्ट अनुभव, एक्सेसिबिलिटी फ़ीडबैक और वैलिडेशन योजना डिज़ाइन करें। आवश्यकता केवल इंटरफ़ेस को तेज़ महसूस कराने की नहीं है। हर पूर्णता क्रम (completion order) के बाद, दृश्यमान स्टेट को एक प्रामाणिक सर्वर स्टेट और यूज़र के अभी भी पेंडिंग इरादों (intents) से स्पष्ट किया जा सकने योग्य होना चाहिए।
यह प्रश्न सीनियर फ़्रंटएंड, UI इन्फ्रास्ट्रक्चर और फ़्रंटएंड सिस्टम-डिज़ाइन साक्षात्कारों के लिए उपयुक्त है। सार्वजनिक फ़्रंटएंड साक्षात्कार सामग्री स्पष्ट रूप से optimistic अपडेट्स, रिक्वेस्ट रेस, त्रुटि स्थितियों और रोलबैक को कवर करती है, जबकि 2025 का एक सार्वजनिक साक्षात्कार रिकॉर्ड optimistic-अपडेट सिद्धांतों और उपयोग के मामलों के बारे में फॉलो-अप प्रश्नों का वर्णन करता है। वे स्रोत विषय की वर्तमान प्रासंगिकता का समर्थन करते हैं; वे किसी कंपनी-विशिष्ट प्रश्न या साक्षात्कार आवृत्ति को स्थापित नहीं करते हैं। श्रेणी frontend है क्योंकि मुख्य कार्य ब्राउज़र-साइड एसिंक्रोनस स्टेट और इंटरैक्शन डिज़ाइन है। सर्वर कॉनक्रेन्सी नियंत्रण उस डिज़ाइन का एक इनपुट है, प्राथमिक कार्यान्वयन लक्ष्य नहीं।
साक्षात्कारकर्ता क्या मूल्यांकन करता है
पहला संकेत यह है कि क्या उम्मीदवार प्रामाणिक स्टेट (authoritative state) को सट्टा स्टेट (speculative state) से अलग करता है। कैशे में एक ऑब्जेक्ट को बदलना और रोलबैक के लिए एक पुराना स्नैपशॉट सहेजना एक अलग-थलग (isolated) अनुरोध के लिए काम करता है। यह तब टूट जाता है जब बाद का optimistic कार्य उसी ऑब्जेक्ट पर निर्भर करता है। एक मज़बूत मॉडल नवीनतम पुष्ट आधार (confirmed base) और पेंडिंग इरादों का एक क्रमबद्ध संग्रह रखता है, फिर दोनों से रेंडर किए गए दृश्य को प्राप्त करता है।
दूसरा संकेत म्यूटेशन सिमेंटिक्स है। "केवल नवीनतम रिस्पॉन्स रखें" एक क्लाइंट रेंडर पाथ की सुरक्षा करता है, लेकिन यह सर्वर द्वारा पुराने अनुरोध को अंतिम रूप से संसाधित होने से नहीं रोक सकता है। उम्मीदवार को यह तय करना होगा कि क्या ऑपरेशन्स को क्रमबद्ध (serialized) किया गया है, समेकित (coalesced) किया गया है, क्रमविनिमेय (commutative) बनाया गया है, या सर्वर-लागू आदेश सौंपा गया है। "शीर्षक को B पर सेट करें," "एक से बढ़ाएं," "टॉगल करें," "हटाएं," और एक भुगतान कमांड के लिए विकल्प बदल जाता है।
तीसरा संकेत चयनात्मक रिकवरी है। जब ऑपरेशन B सबमिट होने के बाद ऑपरेशन A विफल हो जाता है, तो A से पहले के स्नैपशॉट को रीस्टोर करने से B मिट सकता है। एक मजबूत उत्तर विफल ऑपरेशन को हटाता है या चिह्नित करता है, पुष्ट आधार को केवल एक वैध प्रामाणिक रिस्पॉन्स से आगे बढ़ाता है, और शेष इरादों को फिर से चलाता है (replays)। यदि सर्वर वर्ज़न कॉन्फ्लिक्ट रीप्ले को असुरक्षित बनाता है, तो UI वर्तमान सर्वर मान को सतह पर लाता है और एक सुविचारित समाधान मांगता है।
अंतिम संकेत प्रोडक्शन अनुशासन है: पेंडिंग और त्रुटि स्थितियां कीबोर्ड और सहायक तकनीक के साथ काम करने योग्य बनी रहती हैं; कैंसिलेशन को सर्वर रोलबैक समझने की भूल नहीं की जाती है; और टेस्ट केवल सुखद मार्ग (happy path) को मान्य करने के बजाय प्रत्येक रिस्पॉन्स क्रम, विफलता क्रम, रीफ़ेच रेस, पुनः प्रयास और कॉन्फ्लिक्ट को बाध्य करते हैं।
उत्तर देने से पहले स्पष्ट करने योग्य प्रश्न
- किसी ऑपरेशन का क्या अर्थ है? एक निरपेक्ष
setTitle("B")पहले के शीर्षक ड्राफ्ट का स्थान ले सकता है, जबकिincrement(1)के लिए दोनों ऑपरेशन्स को कमिट करने की आवश्यकता हो सकती है। एकtoggle()कमांड पुनः प्रयासों के तहत अस्पष्ट है; एक स्पष्ट लक्षित मान अधिक सुरक्षित है। ऑपरेशन सिमेंटिक्स यह निर्धारित करते हैं कि क्या समेकन (coalescing) मान्य है। - क्या यूज़र सेव पेंडिंग रहने के दौरान दोबारा सबमिट कर सकता है? कंट्रोल को अक्षम करना सरल क्रमांकन (serialization) देता है लेकिन संपादन अनुभव का उल्लंघन कर सकता है। यदि निरंतर इनपुट की आवश्यकता है, तो स्थानीय ड्राफ्ट को अलग से सुरक्षित रखें और या तो सबमिशन को कतारबद्ध/समेकित करें या वर्ज़न वाले समानांतर प्रोटोकॉल का उपयोग करें।
- कौन सा सिस्टम राइट ऑर्डर तय करता है? यदि सर्वर केवल बिना शर्त अंतिम-आगमन-जीतता है (last-arrival-wins) राइट्स प्रदान करता है, तो क्लाइंट को ऑर्डर-निर्भर सेव को क्रमबद्ध करना होगा। यदि API आधार वर्ज़न या क्लाइंट अनुक्रम को स्वीकार करता है और पुराने कार्य को अस्वीकार करता है, तो नियंत्रित समानता (controlled parallelism) संभव हो जाती है।
- क्या optimistic क्रिया प्रतिवर्ती (reversible) और कम जोखिम वाली है? लाइक्स, लेबल और ड्राफ्ट अक्सर optimistic फ़ीडबैक के अनुकूल होते हैं। भुगतान, विनाशकारी क्रियाएं, अनुमति-संवेदनशील परिवर्तन और अपरिवर्तनीय बाहरी प्रभावों वाली क्रियाओं को सफलता का दिखावा करने के बजाय पुष्टि या पेंडिंग स्थिति की आवश्यकता हो सकती है।
- क्या कोई बैकग्राउंड स्रोत उसी रिकॉर्ड को अपडेट कर सकता है? रीफ़ेच, सब्सक्रिप्शन, दूसरा ब्राउज़र टैब और सहयोगी आधार को बदल सकते हैं। स्टेट मॉडल को एक रिसोर्स वर्ज़न की पहचान करनी चाहिए और यह परिभाषित करना चाहिए कि क्या पेंडिंग इरादों को एक नए आधार पर सुरक्षित रूप से फिर से चलाया जा सकता है।
- यूज़र को क्या अनुभव होना चाहिए? स्पष्ट करें कि क्या किसी व्यक्तिगत पंक्ति को पेंडिंग, पुनः प्रयास और कॉन्फ्लिक्ट संकेतकों की आवश्यकता है; क्या फ़ोकस स्थानांतरित हो सकता है; और प्रत्येक कीस्ट्रोक के लिए लाइव-रीजन संदेश उत्पन्न किए बिना किन सेव या विफलता संदेशों की घोषणा की जानी चाहिए।
30-सेकंड उत्तर रूपरेखा
"मैं नवीनतम सर्वर-पुष्ट टास्क को आधार के रूप में रखूंगा और प्रत्येक स्थानीय सबमिशन को एक पहचाने गए इरादे (intent) के रूप में दर्शाऊंगा। UI उस आधार पर पेंडिंग इरादों को रेंडर करता है। शीर्षक प्रतिस्थापन के लिए, मेरा डिफ़ॉल्ट प्रति टास्क एक इन-फ़्लाइट सेव है और कतारबद्ध ड्राफ्ट्स को नवीनतम शीर्षक में समेकित करना है; केवल एक रिक्वेस्ट ID सर्वर को पुराने अनुरोध को अंतिम रूप से लागू करने से नहीं रोक सकती है। सफलता पर मैं लौटाए गए विहित वर्ज़न को अपनाता हूं, उस इरादे को हटाता हूं, और किसी भी शेष इरादे को फिर से चलाता हूं। विफलता पर मैं केवल विफल इरादे को हटाता हूं, न कि पूरे पुराने स्नैपशॉट को रीस्टोर करता हूं। एक वर्ज़न कॉन्फ्लिक्ट स्वचालित रीप्ले को रोकता है और दोनों मान दिखाता है। मैं प्रति-आइटम पेंडिंग और त्रुटि स्थिति को उजागर करूंगा, फ़ोकस बनाए रखूंगा, और पुन: व्यवस्थित रिस्पॉन्स, मिश्रित सफलता और विफलता, रीफ़ेच रेस, पुनः प्रयास, कॉन्फ्लिक्ट और ऑफ़लाइन रिकवरी का परीक्षण करूंगा।"
चरण-दर-चरण गहन विश्लेषण
1. लाइब्रेरी चुनने से पहले एक इनवेरिएंट परिभाषित करें
प्रत्येक रिसोर्स के लिए, एक पुष्ट base और एक क्रमबद्ध pending सूची रखें। प्रत्येक पेंडिंग प्रविष्टि में एक स्थिर क्लाइंट ऑपरेशन ID, इरादा और पेलोड, उसका सबमिशन क्रम और उसकी वर्तमान स्थिति होती है। प्रदर्शित स्थिति एक शुद्ध प्रक्षेपण (projection) है:
view = fold(base, pending in logical order, applyIntent)इनवेरिएंट यह है: रेंडर किया गया दृश्य नवीनतम स्वीकृत सर्वर स्टेट और प्रत्येक स्थानीय इरादे के योग के बराबर होता है जो अभी भी लागू होने के योग्य है। यह मॉडल एक देर से आए रीफ़ेच या रिस्पॉन्स को स्क्रीन को ओवरराइट करने के निर्देश के बजाय सामंजस्य (reconciliation) का एक इनपुट बनाता है।
React का optimistic रिड्यूसर पैटर्न इसी अलगाव का समर्थन करता है: जब कोई Action पेंडिंग रहने के दौरान आधार मान बदलता है, तो React नए आधार के विरुद्ध रिड्यूसर को फिर से चला सकता है। एक कैशे लाइब्रेरी म्यूटेशन लाइफ़साइकिल कॉलबैक का प्रबंधन कर सकती है, लेकिन यह उत्पाद के ऑपरेशन सिमेंटिक्स का चयन नहीं करती है। इनवेरिएंट उपयोगी रहता है चाहे कार्यान्वयन React स्टेट, TanStack Query, किसी अन्य क्लाइंट कैशे या कस्टम स्टोर का उपयोग करता हो।
तदर्थ (ad hoc) सिंक्रोनाइज़ेशन प्रभावों के साथ serverTask, formTask, और optimisticTask नामक तीन असंबंधित प्रतियां न रखें। भेजे न गए फ़ॉर्म ड्राफ्ट को अलग रखें क्योंकि टाइपिंग अभी म्यूटेशन नहीं है। एक बार सबमिट करने के बाद, इसे एक स्थिर पहचान वाले इरादे में बदलें।
2. लेटेंसी से नहीं, ऑपरेशन से ऑर्डरिंग चुनें
तीन उपयोगी नीतियां हैं:
| नीति | उपयुक्त मामला | लागत या जोखिम |
|---|---|---|
| प्रति रिसोर्स क्रमबद्ध करें (Serialize per resource) | ऑर्डर-निर्भर राइट्स; API में कोई ऑर्डरिंग गार्ड नहीं है | बाद का काम प्रतीक्षा करता है, लेकिन सर्वर ऑर्डर सिद्ध करने योग्य है |
| क्रमबद्ध और समेकित करें (Serialize and coalesce) | केवल नवीनतम अनसेंड मान मायने रखता है, जैसे बार-बार शीर्षक सबमिशन | मध्यवर्ती सबमिट किए गए मान जानबूझकर छोड़ दिए जाते हैं |
| सर्वर अनुबंध के साथ समानांतर (Parallel with a server contract) | स्वतंत्र या क्रमविनिमेय ऑपरेशन्स, या API आधार वर्ज़न/क्लाइंट अनुक्रम लागू करता है | अधिक थ्रूपुट, लेकिन सामंजस्य और कॉन्फ्लिक्ट स्पष्ट हैं |
इस शीर्षक संपादक के लिए, टास्क ID द्वारा क्रमबद्ध करें और कतारबद्ध न भेजे गए शीर्षक परिवर्तनों को समेकित करें। यदि A इन-फ़्लाइट है और B सबमिट किया गया है, तो B को आशावादी रूप से दिखाएं लेकिन अगले नेटवर्क राइट के रूप में केवल B को रखें। A के सेटल होने के बाद, नवीनतम स्वीकृत वर्ज़न के विरुद्ध B भेजें। TanStack Query दस्तावेज़ बताता है कि म्यूटेशन्स अन्यथा समानांतर में चलते हैं और सीरियल निष्पादन के लिए म्यूटेशन स्कोप प्रदान करते हैं; उसी नीति को उस लाइब्रेरी के बिना भी लागू किया जा सकता है।
समानांतर अनुरोध केवल मजबूत सिमेंटिक्स के साथ सुरक्षित हैं। एक API बासी आधार वर्ज़न को अस्वीकार कर सकता है, एक संपादन सत्र के लिए एक मोनोटोनिक रूप से बढ़ते क्लाइंट अनुक्रम को स्वीकार कर सकता है, या ऐसे ऑपरेशन को उजागर कर सकता है जो वास्तव में क्रमविनिमेय है। React का दस्तावेज़ीकरण यह भी चेतावनी देता है कि कस्टम async Transitions रिक्वेस्ट क्रम की गारंटी नहीं देते हैं; एक उच्च-स्तरीय ऑर्डर की गई Action या एक स्पष्ट कतार अभी भी आवश्यक है। केवल ब्राउज़र में नवीनतम रिक्वेस्ट ID को ट्रैक करना एक पुराने रिस्पॉन्स को दृश्यमान B को ओवरराइट करने से रोकता है, लेकिन सर्वर अभी भी A को अंतिम रूप से स्टोर कर सकता है। A को निरस्त (abort) करना भी यह साबित नहीं करता है कि सर्वर ने इसे कमिट नहीं किया है।
3. आगमन क्रम पर भरोसा किए बिना सफलता का सामंजस्य करें
प्रत्येक रिस्पॉन्स को ऑपरेशन की पहचान करनी चाहिए और विहित रिसोर्स के साथ उसका वर्ज़न लौटाना चाहिए। क्रमांकन के साथ, सक्रिय ऑपरेशन को संभालें, लौटाए गए आधार को अपनाएं, ऑपरेशन को हटाएं, फिर कतारबद्ध इरादे को फिर से चलाकर दृश्य प्राप्त करें। कतारबद्ध B दृश्यमान रहता है जबकि A पूरा होता है, इसलिए स्क्रीन वापस A पर नहीं कूदती है।
नियंत्रित समानता के साथ, किसी रिस्पॉन्स को उसकी ऑपरेशन ID से मिलाएँ और उसके रिसोर्स वर्ज़न या पावती (acknowledgement) को मान्य करें। केवल इसलिए सीधे रिस्पॉन्स डेटा असाइन न करें क्योंकि प्रॉमिस हल (resolve) हो गया है। वर्तमान पुष्ट वर्ज़न से पुराना रिस्पॉन्स आधार को प्रतिस्थापित नहीं कर सकता है। केवल उन्हीं ऑपरेशन्स को हटाएं जिन्हें रिस्पॉन्स वास्तव में स्वीकार करता है। यदि सर्वर एक विहित परिवर्तन लौटाता है, जैसे कि शीर्षक को ट्रिम करना, तो बाद के स्थानीय इरादों को फिर से चलाने से पहले उस परिणाम को नए आधार के रूप में उपयोग करें।
एक बैकग्राउंड रीफ़ेच उसी नियम का पालन करता है। यदि यह वर्ज़न 12 लौटाता है जबकि वर्तमान आधार वर्ज़न 11 है, तो वर्ज़न 12 आधार को आगे बढ़ा सकता है; पेंडिंग इरादों को फिर से लागू किया जाता है यदि उनके सिमेंटिक्स इसकी अनुमति देते हैं। वर्ज़न 10 के साथ एक रीफ़ेच पुराना साक्ष्य है और आधार को पीछे नहीं ले जा सकता है।
4. स्नैपशॉट से नहीं, ऑपरेशन द्वारा रिकवर करें
मान लीजिए कि A और B आशावादी रूप से दृश्यमान हैं, फिर A विफल हो जाता है। A से पहले कैप्चर किए गए ऑब्जेक्ट को रीस्टोर करने से B संपार्श्विक क्षति (collateral damage) के रूप में हट जाता है। इसके बजाय, A को विफल चिह्नित करें या इसे हटाएं, B को रखें, और प्रोजेक्शन की पुनर्गणना करें। एक निरपेक्ष शीर्षक असाइनमेंट के लिए, B को अभी भी वर्तमान आधार के विरुद्ध भेजा जा सकता है। ऑर्डर-निर्भर डेल्टा के लिए, B को प्रतीक्षा करने, पुनर्गणना करने या अस्वीकार करने की आवश्यकता हो सकती है क्योंकि इसका मूल आधार अब मान्य नहीं है।
विफलताओं को कार्रवाई योग्य स्थितियों में अलग करें:
- एक वैलिडेशन या अनुमति विफलता तब तक अंतिम होती है जब तक कि यूज़र इनपुट या एक्सेस नहीं बदलता; अस्वीकृत मान और सर्वर का कारण कंट्रोल के पास दिखाएं।
- एक क्षणिक नेटवर्क विफलता पुनः प्रयास को प्रदर्शित कर सकती है। उसी ऑपरेशन पहचान का पुन: उपयोग केवल तभी करें जब सर्वर अनुबंध उस पुनः प्रयास को सुरक्षित बनाता है; अन्यथा पहले सामंजस्य करें कि क्या मूल राइट कमिट हुआ था।
- एक वर्ज़न कॉन्फ्लिक्ट का अर्थ है कि आधार कहीं और बदल गया है। वर्तमान सर्वर मान को अपनाएं या लाएं, स्थानीय इरादे से इसकी तुलना करें, और केवल सिद्ध मर्ज नियम वाले ऑपरेशन को स्वचालित रूप से फिर से चलाएं। शीर्षक कॉन्फ्लिक्ट के लिए, चुपचाप किसी एक का चयन करने के बजाय वर्तमान और प्रस्तावित मान प्रस्तुत करें।
- एक अज्ञात परिणाम का अर्थ है कि अनुरोध कमिट हो गया होगा भले ही रिस्पॉन्स खो गया हो। "स्थानीय रूप से रोलबैक करें और नए के रूप में पुनः प्रयास करें" एक गैर-आइडेम्पोटेंट क्रिया को डुप्लिकेट कर सकता है।
कुछ क्रियाएं optimistic नहीं होनी चाहिए। यदि किसी विफलता को पूर्ववत करना कठिन होगा, प्राधिकरण बदलता है, पैसे लेता है, या भ्रामक कानूनी या व्यावसायिक स्थिति बनाता है, तो तत्काल पेंडिंग पावती दिखाएं और सर्वर द्वारा इसे स्वीकार करने के बाद ही पुष्टि करें।
5. सट्टा स्टेट को दृश्यमान और सुलभ बनाएं
Optimistic का अर्थ पुष्ट (confirmed) से अप्रभेद्य होना नहीं है। प्रभावित टास्क को सेविंग के रूप में चिह्नित करें, सबमिट किए गए मान को बनाए रखें, और एक स्थानीय पुनः प्रयास या कॉन्फ्लिक्ट क्रिया प्रदान करें। असंबंधित टास्क को अक्षम न करें। यदि क्रमांकन का उपयोग किया जाता है, तो सक्रिय सेव को एक नए कतारबद्ध मान से अलग करें ताकि इंस्ट्रूमेंटेशन और त्रुटि संदेश सही इरादे से जुड़ें।
जब कोई सेव सफल होता है, विफल होता है, या कैशे सामंजस्य करता है, तो कीबोर्ड फ़ोकस सुरक्षित रखें। एक स्थिति क्षेत्र फ़ोकस को स्थानांतरित किए बिना "टास्क शीर्षक सहेजा जा रहा है," "टास्क शीर्षक सहेजा गया," या "सहेजना विफल रहा" की घोषणा कर सकता है। W3C की status भूमिका में विनीत (polite) लाइव-रीजन सिमेंटिक्स हैं; संदेश परिवर्तन से पहले स्थिति कंटेनर बनाएं और प्रत्येक कीस्ट्रोक की घोषणा करने से बचें। फ़ील्ड-विशिष्ट त्रुटियों को फ़ील्ड से कनेक्ट करें और केवल रंग पर निर्भर किए बिना दृश्य स्थिति को समझने योग्य रखें।
6. स्टेट मशीन का परीक्षण करें और नीति का निरीक्षण करें
प्रत्येक नीति को एक ही ट्रेस की अनुमति देने का नाटक करने के बजाय चयनित ऑर्डरिंग नीति का परीक्षण करें। क्रमबद्ध पथ के लिए, पुष्टि करें कि B दृश्यमान है लेकिन तब तक डिस्पैच नहीं किया जाता जब तक A सेटल नहीं हो जाता; फिर A की सफलता या विफलता के बाद B की सफलता या विफलता, रिस्पॉन्स हानि के बाद सामंजस्य, और एक सर्वर परिवर्तन को कवर करें। किसी भी समर्थित समानांतर पथ के लिए, A-फिर-B और B-फिर-A प्रोसेसिंग और रिस्पॉन्स क्रम को बाध्य करने के लिए एक नियंत्रणीय ट्रांसपोर्ट और सर्वर स्टब का उपयोग करें। प्रत्येक इवेंट के बाद रेंडर किए गए प्रोजेक्शन, कतारबद्ध ऑपरेशन्स, पुष्ट वर्ज़न और अंतिम सर्वर मान की पुष्टि करें।
फिर एक म्यूटेशन पेंडिंग रहने के दौरान एक नया और एक पुराना रीफ़ेच, एक सहयोगी कॉन्फ्लिक्ट, ऑफ़लाइन-से-ऑनलाइन रिकवरी, कंपोनेंट अनमाउंट और रीमाउंट, बार-बार सबमिट करना, और सर्वर कमिट होने के बाद कैंसिलेशन इंजेक्ट करें। कीबोर्ड फ़ोकस, स्थिति घोषणाओं, पुनः प्रयास लेबल और यह सत्यापित करें कि कोई त्रुटि सही टास्क और ऑपरेशन से संबंधित है।
प्रोडक्शन टेलीमेट्री को कथित विलंबता को शुद्धता से अलग करना चाहिए: optimistic रेंडर लेटेंसी, पुष्टिकरण लेटेंसी, विफलता और रोलबैक दर, कॉन्फ्लिक्ट दर, कतार प्रतीक्षा, समेकित ऑपरेशन गणना, पुनः प्रयास गणना, और सामंजस्य बेमेल। एक तेज़ इंटरफ़ेस जो अक्सर खुद को एक आश्चर्यजनक मान में सुधारता है, उत्पाद अनुबंध में विफल रहा है।
उच्च-गुणवत्ता वाला नमूना उत्तर
"मैं यह पूछकर शुरू करूंगा कि क्या प्रत्येक सबमिट किए गए शीर्षक को सहेजा जाना चाहिए या केवल यूज़र का नवीनतम इरादा मायने रखता है। यहां नवीनतम शीर्षक मायने रखता है, API रिसोर्स वर्ज़न लौटाता है, और मुझे एक टास्क के लिए समानांतर राइट्स की आवश्यकता नहीं है। इसलिए मैं निरंतर संपादन की अनुमति दूंगा लेकिन टास्क ID द्वारा नेटवर्क सेव को क्रमबद्ध करूंगा। यदि A इन-फ़्लाइट है और यूज़र B सबमिट करता है, तो स्क्रीन B को तुरंत दिखाती है और B समेकित कतारबद्ध इरादा बन जाता है।
उस टास्क के स्टेट में एक पुष्ट आधार, एक सक्रिय ऑपरेशन और अधिकतम एक कतारबद्ध शीर्षक इरादा होता है। प्रत्येक ऑपरेशन में एक क्लाइंट ID और वह आधार वर्ज़न होता है जिसे वह सबमिट करेगा। रेंडर किया गया शीर्षक कतारबद्ध मान है, अन्यथा सक्रिय optimistic मान, अन्यथा पुष्ट शीर्षक है। जब A सफल होता है, तो मैं उसके रिस्पॉन्स से विहित टास्क और वर्ज़न को अपनाता हूं। मैं A को रेंडर नहीं करता क्योंकि B अभी भी पेंडिंग है; मैं नए वर्ज़न के विरुद्ध B भेजता हूं। जब A विफल हो जाता है, तो मैं केवल A को हटाता हूं और विफलता क्षणिक होने पर भी B को सहेजने की पेशकश करता हूं। एक वैलिडेशन या अनुमति विफलता अस्वीकृत इरादे से जुड़ी रहती है।
यदि सर्वर रिपोर्ट करता है कि किसी अन्य यूज़र ने वर्ज़न को आगे बढ़ाया है, तो मैं स्वचालित सबमिशन रोक देता हूं, वर्तमान शीर्षक प्राप्त करता हूं या अपनाता हूं, और समाधान के लिए सर्वर और प्रस्तावित मान दिखाता हूं। मैं किसी पुराने रिस्पॉन्स को अनदेखा करने पर भरोसा नहीं करूंगा, क्योंकि वह सर्वर पर किसी पुराने अनुरोध को अंतिम रूप से राइट करने से नहीं रोक सकता। मैं निरस्त (abort) को रोलबैक के रूप में भी नहीं मानूंगा।
प्रत्येक टास्क अपनी स्वयं की सेविंग, कतारबद्ध, विफल या कॉन्फ्लिक्टेड स्थिति को उजागर करता है। फ़ोकस एडिटर पर रहता है, और पहले से मौजूद एक विनीत स्थिति क्षेत्र प्रत्येक वर्ण की घोषणा किए बिना सबमिशन परिणामों की घोषणा करता है। टेस्ट प्रॉमिस रिज़ॉल्यूशन और सर्वर प्रोसेसिंग को स्वतंत्र रूप से नियंत्रित करते हैं, इसलिए मैं पुन: व्यवस्थित सफलता, मिश्रित विफलताओं, बासी रीफ़ेच, कॉन्फ्लिक्ट्स, खोए हुए रिस्पॉन्स, पुनः प्रयासों, ऑफ़लाइन रिकवरी और अनमाउंट्स के लिए अंतिम UI और सर्वर मान साबित कर सकता हूं।"
सामान्य गलतियां
- म्यूटेशन से पहले का एक स्नैपशॉट सहेजना और किसी भी त्रुटि पर उसे रीस्टोर करना → एक देर से हुई विफलता नए optimistic कार्य को मिटा देती है → विफल ऑपरेशन को हटाएं और पुष्ट आधार और शेष इरादों से पुनर्गणना करें।
- केवल नवीनतम रिस्पॉन्स ID रखना → UI सही दिख सकता है जबकि सर्वर पुराने अनुरोध को अंतिम रूप से कमिट करता है → ऑर्डर-निर्भर राइट्स को क्रमबद्ध करें या सर्वर-लागू वर्ज़न या अनुक्रम सिमेंटिक्स की आवश्यकता रखें।
- एक वैश्विक लोडिंग फ़्लैग का उपयोग करना → असंबंधित कंट्रोल्स फ़्रीज़ हो जाते हैं और किसी विफलता को उसके रिसोर्स से नहीं जोड़ा जा सकता है → रिसोर्स और ऑपरेशन ID द्वारा पेंडिंग और त्रुटि स्थिति को ट्रैक करें।
- प्रत्येक म्यूटेशन को रीप्ले करने योग्य मानना → टॉगल, डेल्टा, डिलीट और अपरिवर्तनीय कमांड में अलग-अलग विफलता सिमेंटिक्स होते हैं → optimistic व्यवहार सक्षम करने से पहले एक स्पष्ट इरादा और मर्ज नियम परिभाषित करें।
- यह मान लेना कि कैंसिलेशन अनुरोध को पूर्ववत कर देता है → सर्वर कैंसिलेशन को देखने से पहले कमिट कर सकता है → प्रामाणिक स्टेट का सामंजस्य करें और अज्ञात परिणामों के लिए पुनः प्रयास डिज़ाइन करें।
- किसी भी फ़ेच को कैशे को ओवरराइट करने देना → एक पुराना रीफ़ेच या देर से आया रिस्पॉन्स पुष्ट स्टेट को पीछे ले जाता है → रिसोर्स वर्ज़न की तुलना करें और नवीनतम आधार पर मान्य पेंडिंग इरादों को फिर से चलाएं।
- UI को त्वरित महसूस कराने के लिए सभी पेंडिंग स्टेट को छिपाना → यूज़र बाद के सुधार की व्याख्या नहीं कर सकते हैं या प्रभावित क्रिया का पुनः प्रयास नहीं कर सकते हैं → optimistic मान को संरक्षित करते हुए स्थानीय सेविंग, विफलता और कॉन्फ्लिक्ट स्थितियों को दिखाएं।
- सबमिशन क्रम में केवल सफलता का परीक्षण करना → सबसे कठिन रेस अनपरीक्षित रह जाती हैं → टेस्ट मैट्रिक्स में रिस्पॉन्स क्रम, सर्वर क्रम, विफलताओं, रीफ़ेच, पुनः प्रयासों और रीमाउंट्स को नियंत्रित करें।
फॉलो-अप प्रश्न और उत्तर
यदि यूज़र कई घंटों तक ऑफ़लाइन संपादित कर सकता है तो क्या बदलता है?
पेंडिंग ऑपरेशन्स टिकाऊ (durable) होने चाहिए, प्रमाणित खाते और रिसोर्स के दायरे में होने चाहिए, और क्लाइंट द्वारा प्राधिकरण और प्रामाणिक वर्ज़न को रीफ़्रेश करने के बाद ही फिर से चलाए जाने चाहिए। इरादे के सिमेंटिक्स और स्थिर ऑपरेशन ID स्टोर करें, कैप्चर किए गए UI स्नैपशॉट नहीं। फिर से कनेक्ट होने पर, पहले आधार प्राप्त करें, उन ऑपरेशन्स को त्याग दें जिन्हें यूज़र ने स्पष्ट रूप से रद्द कर दिया था, और केवल एक वैध मर्ज नियम वाले ऑपरेशन्स को फिर से चलाएं। समाप्त अनुमतियों, हटाए गए रिसोर्स और स्कीमा परिवर्तनों के लिए एक दृश्यमान अवरुद्ध (blocked) स्थिति की आवश्यकता होती है। लंबे ऑफ़लाइन सहयोग के लिए, एक साधारण optimistic कतार अपर्याप्त हो सकती है; उत्पाद को डोमेन-विशिष्ट मर्ज ऑपरेशन्स या एक सहयोगात्मक संपादन प्रोटोकॉल की आवश्यकता हो सकती है।
यदि सर्वर वर्ज़न लौटाता है तो क्या प्रत्येक म्यूटेशन समानांतर में चल सकता है?
नहीं। एक वर्ज़न क्लाइंट को बताता है कि कोई रिस्पॉन्स किस स्टेट का प्रतिनिधित्व करता है, लेकिन यह स्वचालित रूप से यह परिभाषित नहीं करता है कि दो राइट्स को कैसे ऑर्डर या मर्ज किया जाना चाहिए। समानता तब सुरक्षित होती है जब सर्वर सबमिट किए गए आधार वर्ज़न की परमाणु रूप से जांच करता है, एक अनुक्रम लागू करता है, या स्वतंत्र या क्रमविनिमेय ऑपरेशन्स को उजागर करता है। अन्यथा दो निरपेक्ष राइट्स अभी भी गलत क्रम में आ सकते हैं और कमिट हो सकते हैं। एक ऑर्डर-निर्भर रिसोर्स के लिए क्रमांकन (serialization) अक्सर स्पष्ट अनुबंध होता है।
जब सर्वर वास्तविक ID निर्दिष्ट करता है तो आप optimistic निर्माण को कैसे संभालेंगे?
रेंडरिंग से पहले एक स्थिर क्लाइंट ID बनाएं और इसे ऑपरेशन पहचान और अस्थायी सूची कुंजी के रूप में उपयोग करें। सफलता पर, सर्वर ID के मैपिंग को रिकॉर्ड करें और असंबंधित पंक्तियों को रीमाउंट किए बिना पुष्ट निकाय (entity) को बदलें। यदि सर्वर इसका समर्थन करता है तो ऑपरेशन पहचान द्वारा पुनः प्रयास को डुप्लिकेट-मुक्त (deduplicate) करें। यदि निर्माण विफल हो जाता है, तो केवल उस optimistic निकाय को हटाएं या चिह्नित करें। अस्थायी निकाय को लक्षित करने वाले बाद के ऑपरेशन्स को मैपिंग की प्रतीक्षा करनी चाहिए या एक कतार में व्यक्त किया जाना चाहिए जो पुष्टि के बाद लक्ष्य को फिर से लिख सके।
आप जानबूझकर pessimistic UI कब चुनेंगे?
इसे तब चुनें जब सफलता दिखाना यूज़र को भौतिक रूप से गुमराह करेगा, रिकवरी स्थानीय नहीं है, कॉन्फ्लिक्ट्स आम हैं, या क्रिया अपरिवर्तनीय या उच्च जोखिम वाली है। एक भुगतान, अनुमति अनुदान, कानूनी सबमिशन, या विनाशकारी बल्क कार्रवाई वास्तविक पेंडिंग स्थिति प्रदर्शित करते हुए तुरंत क्लिक को स्वीकार कर सकती है, फिर प्रामाणिक पुष्टि के बाद ही सफलता दिखा सकती है। ऐसा परिणाम दावा किए बिना जो अभी तक नहीं हुआ है, इंटरफ़ेस अभी भी उत्तरदायी महसूस हो सकता है।