प्रतिनिधि इंटरव्यू विषय

Frontend इंटरव्यू: Atomics.waitAsync और कैंसिलेशन के साथ Workers का समन्वय

फ्रंटएंडकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

कई Web Workers को लाइव डेटा प्रोसेस करना है जबकि मुख्य थ्रेड रिस्पॉन्सिव बना रहे। वेट-एंड-नोटिफाई प्रोटोकॉल डिज़ाइन करने के लिए Atomics.waitAsync का उपयोग करें, फिर टाइमआउट, कैंसिलेशन, Worker क्रैश और बिना शेयर्ड-मेमोरी सपोर्ट वाले ब्राउज़रों के बारे में समझाएं।

प्रॉम्प्ट और संदर्भ

यह प्रश्न ब्राउज़र कंकरेंसी, शेयर्ड मेमोरी और लाइफसाइकल कंट्रोल का परीक्षण करता है। Atomics.waitAsync() एक Promise लौटाता है जब तक कि किसी शेयर्ड इंटीजर लोकेशन में अपेक्षित मान बना रहता है, जिससे कॉलर UI कार्य को संभालना जारी रख सकता है। यह केवल SharedArrayBuffer द्वारा समर्थित Int32Array या BigInt64Array व्यू को स्वीकार करता है। एक मजबूत उत्तर वेटिंग प्रोटोकॉल को ओनरशिप, कैंसिलेशन और एक उपयोगी फॉलबैक से जोड़ता है।

इंटरव्यूअर क्या मूल्यांकन करता है

  • क्या आप मुख्य थ्रेड पर नॉन-ब्लॉकिंग वेटिंग और Worker में संभावित रूप से ब्लॉकिंग Atomics.wait() के बीच अंतर करते हैं।
  • क्या स्टेट वैल्यूज़, नोटिफिकेशन टाइमिंग, टाइमआउट और डुप्लिकेट नोटिफिकेशन्स के लिए स्पष्ट इनवेरिएंट्स हैं।
  • क्या कैंसिलेशन, पेज हाइडिंग, Worker क्रैश और बफ़र रिलीज़ सुरक्षित हैं।
  • क्या आप क्रॉस-ओरिजिन आइसोलेशन, कैपेबिलिटी डिटेक्शन और Transferable फॉलबैक्स को समझते हैं।

स्पष्टीकरण के लिए प्रश्न

पुष्टि करें कि क्या डेटा ड्रॉप किया जा सकता है, लेटेंसी का लक्ष्य क्या है, प्रोड्यूसर्स और कंज्यूमर्स की संख्या कितनी है, और क्या मेमोरी को Workers के बीच शेयर किया जाना चाहिए। ब्राउज़र सपोर्ट मैट्रिक्स के बारे में पूछें और क्या पेज एक सिक्योर कॉन्टेक्स्ट और क्रॉस-ओरिजिन आइसोलेशन का उपयोग कर सकता है। जांचें कि क्या थर्ड-पार्टी स्क्रिप्ट्स, iframes, या लॉगिन पॉपअप COOP/COEP से प्रभावित होते हैं। परिभाषित करें कि कैंसिलेशन का अर्थ यूज़र स्टॉप, टाइमआउट या पेज टीयरडाउन है।

30-सेकंड उत्तर की रूपरेखा

मैं शेयर्ड रीजन को कंट्रोल वर्ड्स और डेटा स्लॉट्स में विभाजित करूंगा, जिसमें 0=waiting, 1=ready, 2=cancelled और 3=closed जैसी वर्ज़न की गई स्टेट्स का उपयोग किया जाएगा। एक कंज्यूमर स्टेट को एटॉमिक रूप से पढ़ता है और केवल तभी Atomics.waitAsync को कॉल करता है जब वह प्रतीक्षा कर रहा हो। एक प्रोड्यूसर डेटा लिखता है, Atomics.store के साथ स्टेट पब्लिश करता है, और Atomics.notify को कॉल करता है। Promise केवल एक वेक-अप परिणाम है; कंज्यूमर को प्रोसेसिंग से पहले स्टेट को फिर से पढ़ना चाहिए। टाइमआउट और कैंसिलेशन स्टेट ट्रांज़िशन हैं, और बफ़र को प्रत्येक Worker के बाहर निकलने के बाद ही रिलीज़ किया जाता है। असमर्थित ब्राउज़र समान कैंसिलेशन और एरर सिमेंटिक्स वाले Transferable चंक्स का उपयोग करते हैं।

चरण-दर-चरण समाधान

1. शेयर्ड स्टेट और ओनरशिप को परिभाषित करें

कंट्रोल एरिया में प्रोटोकॉल वर्ज़न, स्टेट, सीक्वेंस, लंबाई और क्लोज्ड फ़्लैग शामिल होना चाहिए। एक प्रोड्यूसर केवल अपने स्वामित्व वाले स्लॉट में ही लिखता है और राइट पूरा होने के बाद तत्परता (readiness) पब्लिश करता है। एक कंज्यूमर प्रोसेस करने से पहले स्टेट और सीक्वेंस को पढ़ता है; यह एक नोटिफिकेशन को एक ड्यूरेबल मैसेज नहीं मान सकता। प्रत्येक वेक-अप पर स्टेट की दोबारा जांच की जाती है क्योंकि नोटिफिकेशन्स मर्ज हो सकते हैं, रेस कर सकते हैं, या पहले के बैच को संदर्भित कर सकते हैं।

2. waitAsync और notify का सही उपयोग करें

Atomics.waitAsync(view, index, expected, timeout) पहले लोकेशन की तुलना करता है। एक भिन्न मान not-equal लौटाता है; एक टाइमआउट timed-out लौटाता है; अन्यथा यह एक awaitable Promise लौटाता है। स्टेट बदलने के बाद, प्रोड्यूसर Atomics.notify(view, index, count) को कॉल करता है। प्रोटोकॉल को इस प्रकार दर्शाया जा सकता है:

js
const control = new Int32Array(new SharedArrayBuffer(16));
const WAITING = 0;
const READY = 1;
const CANCELLED = 2;

async function waitForData(timeout = 1000) {
  const result = Atomics.waitAsync(control, 0, WAITING, timeout);
  const outcome = result.async ? await result.value : result.value;
  const state = Atomics.load(control, 0);
  return { outcome, state };
}

function publishData() {
  Atomics.store(control, 0, READY);
  Atomics.notify(control, 0, 1);
}

3. कैंसिलेशन, टाइमआउट और क्लोज़ स्टेट्स जोड़ें

मौजूदा Promise को बाधित (interrupt) करने का प्रयास न करें। इसके बजाय कैंसिलेशन स्टेट लिखें और वेटर्स को सूचित करें। ok, timed-out, या not-equal प्राप्त करने के बाद, वेटर स्टेट को फिर से पढ़ता है और जारी रखने, पुनः प्रयास करने या बाहर निकलने का विकल्प चुनता है। क्लोज़ करने के लिए पहले प्रोडक्शन को रोका जाता है, फिर रीजन को क्लोज्ड मार्क किया जाता है और प्रत्येक वेटर को सूचित किया जाता है; Worker का बाहर निकलना कन्फर्म होने के बाद ही बफ़र को रिलीज़ किया जाना चाहिए।

4. रेस कंडीशन्स और बैकप्रेशर को संभालें

मल्टीपल प्रोड्यूसर्स को स्लॉट क्लेम करने के लिए CAS या एक एलोकेटर की आवश्यकता होती है; उन्हें एक साथ एक ही सीक्वेंस पर नहीं लिखना चाहिए। जब कतार भर जाती है, तो प्रोडक्ट कॉन्ट्रैक्ट के अनुसार ड्रॉपिंग, ओवरराइटिंग या बैकप्रेशर चुनें, और डेप्थ व ड्रॉप्स को रिकॉर्ड करें। एक कंज्यूमर को एक वेक-अप को एक मैसेज के रूप में व्याख्या करने के बजाय एक लूप में सभी पब्लिश किए गए सीक्वेंस नंबरों को ड्रेन करना चाहिए।

5. क्रैश और पेज लाइफसाइकल को प्रबंधित करें

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

6. कैपेबिलिटीज़ का पता लगाएं और सुरक्षित रूप से डिग्रेड करें

स्टार्टअप पर crossOriginIsolated, SharedArrayBuffer, Atomics.waitAsync और Worker सपोर्ट की जांच करें। क्रॉस-ओरिजिन आइसोलेशन थर्ड-पार्टी रिसोर्स और पॉपअप व्यवहार को बदल देता है, इसलिए परफॉर्मेंस सिक्योरिटी पॉलिसी को कमजोर करने का कोई कारण नहीं है। आवश्यक कैपेबिलिटीज़ के बिना, कैंसिलेशन, टाइमआउट, प्रोग्रेस और एरर फ़ील्ड्स को बनाए रखते हुए Transferable ArrayBuffer चंक्स या साधारण postMessage का उपयोग करें। पाथ शेयर और टेल लेटेंसी को मापें।

मॉडल उच्च-गुणवत्ता वाला उत्तर

मैं एक वर्ज़न्ड कंट्रोल रीजन बनाने से पहले कैपेबिलिटीज़ का पता लगाऊंगा और सिक्योर-कॉन्टेक्स्ट तथा क्रॉस-ओरिजिन-आइसोलेशन आवश्यकताओं को सत्यापित करूंगा। एक प्रोड्यूसर डेटा लिखने के बाद एटॉमिक रूप से स्टेट पब्लिश करता है और वेटर्स को सूचित करता है। एक कंज्यूमर केवल तभी Atomics.waitAsync को कॉल करता है जब स्टेट वेटिंग में हो, फिर Promise परिणाम की परवाह किए बिना स्टेट और सीक्वेंस को फिर से पढ़ता है। कैंसिलेशन, टाइमआउट और क्लोज़ स्पष्ट स्टेट्स हैं। शटडाउन प्रोडक्शन को रोकता है, वेटर्स को जगाता है, Worker के एग्जिट की पुष्टि करता है, और केवल तभी शेयर्ड मेमोरी को रिलीज़ करता है। ओनरशिप और सीक्वेंस नंबर डुप्लिकेट उपभोग को रोकते हैं, जबकि कतार भरने पर व्यवहार एक नपा-तुला प्रोडक्ट निर्णय होता है। यदि शेयर्ड मेमोरी या API अनुपलब्ध है, तो Transferable चंक्स समान लाइफसाइकल और एरर कॉन्ट्रैक्ट प्रदान करते हैं।

सामान्य गलतियाँ

  • यह मान लेना कि notify प्रति मैसेज एक वेक-अप की गारंटी देता है।
  • मुख्य थ्रेड पर ब्लॉकिंग वेट को कॉल करना और UI को फ्रीज कर देना।
  • शेयर्ड स्टेट और सीक्वेंस को फिर से पढ़े बिना Promise परिणाम पर भरोसा करना।
  • कैंसिलेशन पर तुरंत बफ़र रिलीज़ कर देना जबकि Workers अभी भी चल रहे हों।
  • क्रॉस-ओरिजिन-आइसोलेशन और थर्ड-पार्टी रिसोर्स प्रतिबंधों को नज़रअंदाज़ करना।
  • postMessage पर स्विच करना लेकिन टाइमआउट, कैंसिलेशन या एरर सिमेंटिक्स को छोड़ देना।

फॉलो-अप प्रश्न

आप wait के स्थान पर waitAsync को कब चुनेंगे?

waitAsync कॉलिंग थ्रेड को ब्लॉक किए बिना एक Promise लौटाता है, जो मुख्य थ्रेड और इवेंट-ड्रिवन कोड के लिए उपयुक्त है। wait एक Worker को ब्लॉक कर सकता है, लेकिन केवल तब जब उस Worker का ब्लॉक्ड समय UI या अन्य महत्वपूर्ण कार्य को नुकसान न पहुँचाए। दोनों के लिए स्टेट चेक्स, टाइमआउट और एक क्लोज़ प्रोटोकॉल की आवश्यकता होती है।

नोटिफिकेशन के बाद स्टेट को दोबारा क्यों पढ़ें?

एक नोटिफिकेशन केवल यह बताता है कि कोई स्थिति बदल सकती है। नोटिफिकेशन्स मर्ज हो सकते हैं, किसी प्रतिस्पर्धी को जगा सकते हैं, या पिछले बैच से संबंधित हो सकते हैं। स्टेट, सीक्वेंस और लंबाई को पढ़ने से यह स्थापित होता है कि क्या डेटा वास्तव में उपलब्ध है।

आप कैंसिलेशन के बाद काम होने से कैसे रोकते हैं?

शेयर्ड स्टेट में कैंसिलेशन पब्लिश करें और स्लॉट क्लेम करते समय, प्रोसेसिंग से पहले और परिणाम कमिट करने से पहले इसकी जांच करें। परिणाम मैसेजेस में एक टास्क वर्ज़न शामिल करें; मुख्य थ्रेड रद्द किए गए वर्ज़न के परिणामों को अस्वीकार कर देता है।

शेयर्ड मेमोरी को कब छोड़ देना चाहिए?

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

सार्वजनिक स्रोत

संबंधित प्रश्न