प्रॉम्प्ट और संदर्भ
एक async सेवा अक्सर I/O किए बिना इन-मेमोरी कैश से अनुरोधों को पूरा करती है, फिर भी प्रत्येक कोरूटीन एक टास्क बन जाता है और इवेंट-लूप शेड्यूलिंग की प्रतीक्षा करता है। टीम विश्व स्तर पर asyncio.eager_task_factory सेट करने का प्रस्ताव करती है। ट्रेड-ऑफ का मूल्यांकन करें और एक सुरक्षित रोलआउट का प्रस्ताव दें।
Python दस्तावेज़ बताता है कि eager निष्पादन एक कोरूटीन को सिंक्रोनस रूप से शुरू करता है जब उसका Task बनाया जा रहा होता है; Task केवल तभी शेड्यूल किया जाता है जब कोरूटीन ब्लॉक होता है। यह API Python 3.12 में जोड़ा गया था और यह अवलोकनीय (observable) शेड्यूलिंग सेमेन्टिक्स को बदलता है।
इंटरव्यूअर क्या जांच रहा है
मुख्य बात सिंक्रोनस पूर्णता और एसिंक्रोनस ब्लॉकिंग के बीच अंतर करना और निष्पक्षता, क्रम, अपवाद के समय, रद्दीकरण और TaskGroup पर प्रभावों की व्याख्या करना है। मजबूत उत्तर अनुकूलन को मापी गई सीमाओं तक सीमित करते हैं और इसमें संस्करण जांच, फीचर फ्लैग, रोलबैक और इवेंट-लूप मेट्रिक्स शामिल होते हैं।
पहले पूछने योग्य स्पष्टीकरण प्रश्न
- प्रत्येक डिप्लॉयमेंट में न्यूनतम Python संस्करण क्या है?
- क्या ये कोरूटीन मेमोरी-कैश रीड हैं, या क्या वे नेटवर्क, डेटाबेस, फ़ाइल, या लॉक I/O निष्पादित कर सकते हैं?
- क्या कोड टास्क-निर्माण क्रम, लूप निष्पक्षता, या
call_soonक्रम पर निर्भर करता है? - क्या विफलता, रद्दीकरण, और समय सीमा (deadlines)
TaskGroupया अनुरोध स्कोप के स्वामित्व में हैं? - क्या लक्ष्य टास्क-निर्माण CPU, टेल लेटेंसी (tail latency), या थ्रूपुट है, और आधार रेखा (baseline) क्या है?
30-सेकंड उत्तर ढांचा
“मैं इसे पहले विश्व स्तर पर सक्षम नहीं करूंगा। एक eager factory Task निर्माण के दौरान एक कोरूटीन शुरू करती है, इसलिए कैश हिट एक इवेंट-लूप शेड्यूलिंग टर्न से बच सकता है; एक ब्लॉकिंग कोरूटीन सामान्य रूप से शेड्यूल होता है। यह क्रम, अपवाद के समय और निष्पक्षता को बदलता है: कई सिंक्रोनस टास्क बनाने वाला एक लूप टाइमर और अन्य अनुरोधों में देरी कर सकता है। मैं Python संस्करण की जांच करूंगा, मापे गए कैश कॉल साइटों पर रोल आउट करूंगा, इवेंट-लूप अंतराल (lag) और टेल लेटेंसी की तुलना करूंगा, और तत्काल रोलबैक के लिए डिफ़ॉल्ट फ़ैक्टरी को बनाए रखूंगा।”
चरण-दर-चरण गहन विश्लेषण
चरण 1: डिफ़ॉल्ट और eager मॉडल बताएं
डिफ़ॉल्ट फ़ैक्टरी के साथ, create_task कोरूटीन को जल्द ही चलाने के लिए शेड्यूल करता है। एक eager फ़ैक्टरी के साथ, निर्माण इसे तुरंत तब तक आगे बढ़ाता है जब तक कि यह वापस नहीं आ जाता, अपवाद उत्पन्न नहीं करता, या अपने पहले ब्लॉकिंग await तक नहीं पहुंच जाता। एक सिंक्रोनस पूर्णता शायद कभी इवेंट-लूप कतार में प्रवेश न करे।
loop.set_task_factory(asyncio.eager_task_factory)
task = asyncio.create_task(read_cached(key))इसलिए eager निष्पादन एक अवलोकनीय सिमेंटिक परिवर्तन है, केवल एक तेज़ शेड्यूलर नहीं।
चरण 2: कोरूटीन सीमा चुनें
अच्छे उम्मीदवार छोटे, उच्च-हिट-दर वाले मेमोरी-कैश या मेमोइज़्ड ऑपरेशन हैं। नेटवर्क, डेटाबेस, फ़ाइल, लॉक, या अनबाउंड CPU कार्य करने वाले कोरूटीन को एक पूर्वानुमानित ब्लॉकिंग सीमा बनाए रखनी चाहिए ताकि निर्माण वर्तमान टास्क का एकाधिकार न कर सके।
चरण 3: क्रम और निष्पक्षता का विश्लेषण करें
जब टास्क एक लूप में बनाए जाते हैं, तो eager कोरूटीन निर्माण क्रम में तुरंत पूरे हो सकते हैं, जिससे पहले इवेंट लूप पर निर्भर रहने वाला इंटरलीविंग बदल जाता है। एक बड़ा सिंक्रोनस बैच टाइमर, I/O कॉलबैक और अन्य अनुरोधों में देरी कर सकता है। इवेंट-लूप अंतराल को ट्रैक करें और बैच आकार को सीमित करें।
चरण 4: अपवाद और रद्दीकरण को संभालें
पहले ब्लॉक से पहले उठाया गया अपवाद create_task के पास सामने आ सकता है, जिससे कैप्चर बिंदु और स्टैक आकार बदल जाता है। Task संदर्भ बनाए रखें, और सफाई के बाद CancelledError को प्रसारित होने दें। अनुरोध रद्दीकरण या कैश विफलता को सफल प्रतिक्रिया में बदलने के लिए कभी भी eager मोड का उपयोग न करें।
चरण 5: इसे TaskGroup और समय सीमाओं के साथ संयोजित करें
TaskGroup अभी भी टास्क ट्री, सिबलिंग रद्दीकरण और जॉइन का मालिक है, लेकिन create_task के दौरान एक चाइल्ड पहले ही पूरा हो चुका हो सकता है या विफल हो चुका हो सकता है। संरचित try/except* हैंडलिंग और एक बाहरी समय सीमा का उपयोग करें; यह न मानें कि प्रत्येक चाइल्ड पहले एक कतार में प्रतीक्षा करता है।
async with asyncio.TaskGroup() as group:
user = group.create_task(read_cached("user"))
orders = group.create_task(read_remote("orders"))चरण 6: संस्करणों की जाँच करें और सुविधा का दायरा तय करें
फ़ैक्टरी Python 3.12 से उपलब्ध है। Python 3.14 create_task पर एक eager_start विकल्प भी उजागर करता है। एक बहु-संस्करण सेवा को स्टार्टअप पर रनटाइम को मान्य करना चाहिए और बिना शर्त वैश्विक फ़ैक्टरी परिवर्तन पर स्थानीय कॉल-साइट प्रयोग को प्राथमिकता देनी चाहिए।
चरण 7: रोलबैक मेट्रिक्स के साथ रोल आउट करें
एक स्विच के पीछे केवल-कैश कॉल साइटों पर शुरुआत करें। डिफ़ॉल्ट फ़ैक्टरी के मुकाबले CPU, टास्क-निर्माण समय, कैश-हिट टेल लेटेंसी, इवेंट-लूप अंतराल, अपवाद दर, रद्दीकरण दर और डाउनस्ट्रीम QPS की तुलना करें। यदि निष्पक्षता या त्रुटियां बिगड़ती हैं, तो व्यावसायिक कोड को बदले बिना डिफ़ॉल्ट को पुनर्स्थापित करें।
चरण 8: केवल बेंचमार्क ही नहीं, सिमेंटिक्स का परीक्षण करें
सिंक्रोनस रिटर्न, सिंक्रोनस अपवाद, पहला await, बाहरी रद्दीकरण, कई TaskGroup विफलताएं, समय सीमा, पुनरावर्ती (recursive) टास्क निर्माण, टाइमर निष्पक्षता और मिश्रित कैश/रिमोट बैचों को कवर करें। घटनाओं को रिकॉर्ड करें और क्रम की पुष्टि करें; केवल थ्रूपुट बेंचमार्क शेड्यूलिंग सेमेन्टिक्स को मान्य नहीं कर सकता है।
मॉडल उच्च-गुणवत्ता वाला उत्तर
“Eager निष्पादन छोटे, पूर्वानुमानित कैश कोरूटीन के लिए उपयुक्त है क्योंकि यह एक शेड्यूलिंग टर्न को हटा देता है; यह अप्रत्याशित I/O या लंबे CPU पथों के लिए जोखिम भरा है। मुख्य जोखिम बदला हुआ क्रम, निष्पक्षता और अपवाद समय है। मैं संस्करणों की जांच करूंगा, इसे एक फ्लैग के पीछे स्थानीय रूप से सक्षम करूंगा, डिफ़ॉल्ट रोलबैक बनाए रखूंगा, और इवेंट-लूप अंतराल, टेल लेटेंसी, रद्दीकरण और त्रुटियों की निगरानी करूंगा। TaskGroup और एक साझा समय सीमा बनी रहती है, जैसा कि सामान्य रद्दीकरण और सफाई होती है।”
सामान्य गलतियाँ
- Eager मोड को सेमेन्टिक्स-मुक्त मानना → क्रम और अपवाद समय बदल जाता है → दोनों निष्पादन मॉडलों को लिखें और मापें।
- प्रत्येक कोरूटीन के लिए इसे सक्षम करना → धीमा I/O या CPU वर्तमान टास्क को ब्लॉक करता है → केवल छोटे सिंक्रोनस पथों को कैनरी करें।
- Python संस्करणों की अनदेखी करना → पुराने डिप्लॉयमेंट स्टार्टअप पर विफल होते हैं → रनटाइम को मान्य करें और डिफ़ॉल्ट फ़ैक्टरी बनाए रखें।
- केवल औसत थ्रूपुट को देखना → निष्पक्षता चुपचाप बिगड़ जाती है → लूप-लैग और टेल मेट्रिक्स जोड़ें।
- यह मान लेना कि TaskGroup अपरिवर्तित है → निर्माण-समय की विफलताओं को गलत तरीके से संभाला जाता है → eager चाइल्ड विफलताओं और अपवाद समूहों का परीक्षण करें।
- रद्दीकरण या सफाई त्रुटियों को दबाना → अनुरोध कार्य को लीक करते हैं → रद्दीकरण को संरक्षित करें और रिलीज पथों को सत्यापित करें।
फॉलो-अप प्रश्न और मजबूत प्रतिक्रियाएं
फॉलो-अप 1: क्या एक सिंक्रोनस कैश हिट अभी भी एक Task छोड़ता है?
निर्माण के दौरान Task पहले से ही पूरा हो सकता है। इवेंट-लूप टर्न की आवश्यकता न रखें; लौटाई गई वस्तु को पढ़ें और eager-पूर्णता पथ का स्पष्ट रूप से परीक्षण करें।
फॉलो-अप 2: क्या eager मोड पूर्णता के लिए निर्माण क्रम की गारंटी देता है?
नहीं। यह केवल प्रारंभ समय को बदलता है; एक बार जब कोई कोरूटीन ब्लॉक हो जाता है, तो सामान्य शेड्यूलिंग लागू होती है। यदि व्यावसायिक क्रम मायने रखता है, तो स्पष्ट रूप से समन्वय करें या संचालन कुंजी द्वारा परिणामों को क्रमबद्ध करें।
फॉलो-अप 3: आप कैश-हिट बैच को अनुरोधों को भुखमरी (starve) से कैसे रोकते हैं?
बैच को सीमित करें, उपयुक्त होने पर बैचों के बीच यील्ड (yield) करें, और लूप अंतराल पर नज़र रखें। वैश्विक नीति की तुलना में कम लागत वाली एक कॉल साइट पर eager मोड लागू करना अधिक सुरक्षित है।
फॉलो-अप 4: रिग्रेशन के बाद आप इसे कैसे रोल बैक करते हैं?
स्विच को अक्षम करें, डिफ़ॉल्ट टास्क फ़ैक्टरी को पुनर्स्थापित करें, सत्यापित करें कि मेट्रिक्स आधार रेखा पर वापस आ गए हैं, और निदान के लिए रनटाइम संस्करण और इवेंट क्रम वाले ट्रेस बनाए रखें।
फॉलो-अप 5: eager_start का फ़ैक्टरी से क्या संबंध है?
eager_start एक Task के लिए एक स्पष्ट विकल्प है; फ़ैक्टरी एक इवेंट-लूप डिफ़ॉल्ट नीति है। उन्हें संयोजित करने से पहले सटीक Python-संस्करण हस्ताक्षर और प्राथमिकता की पुष्टि करें।