2009-12-17 4 views
21

के साथ इतना बुरा क्या है Django दुनिया में हर कोई थ्रेडलोकल्स से नफरत करता है (http://code.djangoproject.com/ticket/4280, http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser)। मैंने इस पर आर्मीन के निबंध को पढ़ा (http://lucumr.pocoo.org/2006/7/10/why-i-cant-stand-threadlocal-and-others), लेकिन इसमें से अधिकांश थ्रेडलोकल्स पर टिकाऊ है क्योंकि यह सुरुचिपूर्ण है।थ्रेडलोकल्स

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

इसके अलावा बहुत से जावा ढांचे थ्रेडलोकल्स का उपयोग कर रहे हैं, तो उनका मामला पायथन/डीजेगो से अलग कैसे है?

+0

threadlocals बिना उपडोमेन बहु किरायेदारी को लागू करने की कोशिश की, मैं पूरी तरह से सहानुभूति कर सकते हैं । कुछ गंभीर निराशा के बाद, थ्रेडलोकल्स वास्तव में जाने का एकमात्र तरीका बन गया। मैंने उनके खिलाफ तर्क पढ़ा, और वे पर्याप्त मजबूत नहीं थे। मुझे लगता है कि थ्रेडलोकल्स का उपयोग करने से इनकार करना प्राथमिक कारणों में से एक है कि साइट्स फ्रेमवर्क कुछ परिदृश्यों के लिए बेकार है। दिलचस्प होगा अगर वे कभी भी यह पता लगाएंगे कि कैसे कानूनी रूप से https://code.djangoproject.com/ticket/15089 को हल करने के तरीके को हल किया जाए जो कि आपके द्वारा उपयोग किए जा रहे बहु-किरायेदारी के प्रकार के अनुकूल हो सकता है और मैं उनका उपयोग कर रहा हूं। –

+0

Django Cookbook लिंक टूटा हुआ है। निबंध लिंक भी टूटा हुआ है ([संभावित प्रतिस्थापन] (http://www.memonic.com/user/pneff/folder/python/id/1Wg))। –

उत्तर

18

मुझे नहीं लगता कि थ्रेडलोकल्स के साथ कुछ भी गलत है - हाँ, यह एक वैश्विक चर है, लेकिन इसके अलावा यह एक सामान्य उपकरण है। हम इसे इस उद्देश्य के लिए उपयोग करते हैं (मिडलवेयर से वर्तमान अनुरोध के संदर्भ में ग्लोबल संदर्भ में सबडोमेन मॉडल संग्रहीत करते हैं) और यह पूरी तरह से काम करता है।

तो मैं कहता हूं, नौकरी के लिए सही उपकरण का उपयोग करें, इस मामले में थ्रेडलोकल्स आपके मॉडल को सभी मॉडलों के तरीकों के आस-पास सबडोमेन मॉडल को पार करने से कहीं ज्यादा सुरुचिपूर्ण बनाता है (इस तथ्य का जिक्र नहीं कि यह हमेशा संभव नहीं है - जब आप सबडोमेन द्वारा प्रश्नों को सीमित करने के लिए django प्रबंधक विधियों को ओवरराइड कर रहे हैं, उदाहरण के लिए get_query_set में अतिरिक्त कुछ भी पास करने का कोई तरीका नहीं है, उदाहरण के लिए - इसलिए थ्रेडलोकल्स प्राकृतिक और एकमात्र उत्तर है)।

+0

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

+1

निर्भरता छुपाकर एक ऐप को अधिक सुरुचिपूर्ण बनाते हैं? पहली बार मैंने इसे पढ़ा। यह समझने में कि django आपको किसी अन्य तरीके से ऐसा करने नहीं दे सकता है। यह एक django मुद्दा है। लेकिन सुरुचिपूर्ण, चलो उस पर असहमत होने के लिए सहमत हैं। – graffic

2

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

अनुरोध से इसे क्यों पास कर रहा है इसके लायक नहीं है? आप सत्र या उपयोगकर्ता प्रोफ़ाइल में इसे क्यों स्टोर नहीं करते?

जावा के साथ अंतर यह है कि वेब विकास पाइथन/PERL/PHP/रूबी दुनिया की तुलना में कहीं अधिक राज्यमान है, इसलिए लोगों को इस तरह के सभी संदर्भों और सामानों के लिए उपयोग किया जाता है। मुझे नहीं लगता कि यह एक फायदा है, लेकिन यह शुरुआत में ऐसा लगता है।

+0

'आप इसे सत्र या उपयोगकर्ता प्रोफ़ाइल में क्यों स्टोर नहीं करते?' क्योंकि मुझे इसे मॉडल से एक्सेस करने की आवश्यकता है। – agiliq

+0

'आपके मामले में, आप इसे वैश्विक संदर्भ के रूप में अधिक उपयोग करना चाहते हैं' वास्तव में, मैं इसे मिडलवेयर में सेट करना चाहता हूं, और इसे बिना किसी विचार के modles.py में एक्सेसिबल करना है, इसे प्रत्येक बार models.py को भेजना । – agiliq

3

इसके अलावा बहुत से जावा ढांचे थ्रेडलोकल्स का उपयोग कर रहे हैं, तो उनका मामला पायथन/डीजेगो से अलग कैसे है?

सीपीथन के दुभाषिया के पास ग्लोबल इंटरप्रेटर लॉक (जीआईएल) है जिसका अर्थ है कि किसी भी समय केवल एक पायथन थ्रेड को दुभाषिया द्वारा निष्पादित किया जा सकता है। यह मुझे स्पष्ट नहीं है कि पाइथन दुभाषिया कार्यान्वयन को इसे प्राप्त करने के लिए एक से अधिक ऑपरेटिंग सिस्टम थ्रेड का उपयोग करने की आवश्यकता होगी, हालांकि अभ्यास में साइप्टन करता है।

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

ये सिंक्रनाइज़ेशन समस्या केवल "साझा-परिवर्तनीय स्थिति" के साथ उत्पन्न होती है। यदि राज्य म्यूटेबल नहीं है, या थ्रेडलोकल के मामले में इसे साझा नहीं किया जाता है, तो यह जावा प्रोग्रामर को हल करने के लिए एक कम जटिल समस्या है।

एक सीपीथन प्रोग्रामर को अभी भी दौड़ की स्थिति की संभावना से निपटना होगा, लेकिन कुछ अधिक गूढ़ जावा समस्याओं (जैसे प्रकाशन) को दुभाषिया द्वारा संभावित रूप से हल किया जाता है।

एक सीपीथन प्रोग्रामर के पास पाइथन-कॉल करने योग्य सी या सी ++ कोड में प्रदर्शन महत्वपूर्ण कोड कोड करने का विकल्प भी है जहां जीआईएल प्रतिबंध लागू नहीं होता है। तकनीकी रूप से जावा प्रोग्रामर के पास जेएनआई के माध्यम से एक समान विकल्प होता है, लेकिन यह पाइथन की तुलना में जावा में सही या गलत तरीके से स्वीकार्य माना जाता है।

22

मैं थ्रेडलोकल्स के इस प्रकार के उपयोग से बचता हूं, क्योंकि यह एक अंतर्निहित गैर-स्थानीय युग्मन प्रस्तुत करता है। मैं अक्सर सभी प्रकार के गैर-HTTP-उन्मुख तरीकों (स्थानीय प्रबंधन आदेश, डेटा आयात/निर्यात इत्यादि) में मॉडल का उपयोग करता हूं। यदि मैं models.py में कुछ थ्रेडलोकल्स डेटा तक पहुंचता हूं, तो अब मुझे यह सुनिश्चित करने के लिए कुछ रास्ता खोजना होगा कि जब भी मैं अपने मॉडल का उपयोग करता हूं, यह हमेशा पॉप्युलेट होता है, और यह काफी बदसूरत हो सकता है।

मेरी राय में, अधिक स्पष्ट कोड क्लीनर और अधिक रखरखाव योग्य है। यदि किसी मॉडल विधि को संचालित करने के लिए उपडोमेन की आवश्यकता होती है, तो उस तथ्य को पैरामीटर के रूप में उपडोमेन को स्वीकार करने के द्वारा यह तथ्य स्पष्ट किया जाना चाहिए।

अगर मुझे थ्रेडलोकल्स में अनुरोध डेटा संग्रहीत करने के लिए बिल्कुल कोई रास्ता नहीं मिल सका, तो मैं कम से कम एक अलग मॉड्यूल में रैपर विधियों को लागू करता हूं जो थ्रेडलोकल्स तक पहुंचते हैं और आवश्यक डेटा के साथ मॉडल विधियों को कॉल करते हैं। इस तरह model.py आत्मनिर्भर रहता है और मॉडल थ्रेडलोकल्स युग्मन के बिना उपयोग किया जा सकता है।

+1

कार्ल: मैं इस ब्रेक को इलाके से सहमत करता हूं, लेकिन अगर मुझे अपने 'फिल्टर' कॉल के सभी 100% में 'सबडोएन' डेटा पास करना है, तो वह खराब तरीके से DRY को तोड़ता नहीं है। यही कारण है कि मुझे लगता है कि यह इस मामले में एक स्वीकार्य व्यापार है। – agiliq

+7

व्यापार मामले इस मामले में स्वीकार्य हो सकता है; केवल आप ही वह कॉल कर सकते हैं। आपने पूछा "थ्रेडलोकल्स के साथ इतना बुरा क्या है," इसलिए मैंने जवाब दिया :-) मैंने यह भी बताया कि अगर मुझे लगता है कि ट्रेडऑफ इसके लायक है तो मैं नुकसान कैसे कम कर सकता हूं। –

+1

Django में दृष्टिकोण अनुरोध मिडलवेयर बनाना होगा जो थ्रेड-स्थानीय डेटा को अनुरोध ऑब्जेक्ट से जोड़ता है। यह सत्र ढांचे के लिए Django के डिजाइन का पालन करता है, जिसके माध्यम से मिडलवेयर वर्ग सुनिश्चित करता है कि पर्याप्त डेटा मौजूद है कि जब आप कुछ प्रति-अनुरोध डेटा तक पहुंचना चाहते हैं तो आपका एप्लिकेशन झटका नहीं देता है। इसका यह भी अर्थ है कि इस तरह के स्पर्शपूर्ण युग्मन केवल विचारों के माध्यम से सुलभ है, जिसे मैं अपने आवेदन को डिजाइन करने के लिए पहले किसी को भी सीमित नहीं मानता। –

0

मैंने पाया है कि थ्रेडलोकल का उपयोग HTTP अनुरोध/प्रतिक्रिया वातावरण (यानी कोई भी वेबपैप) में निर्भरता इंजेक्शन को लागू करने का एक शानदार तरीका है। आपने केवल अनुरोध प्राप्त करने पर थ्रेड में आवश्यक ऑब्जेक्ट को 'इंजेक्ट' करने के लिए एक सर्वलेट फ़िल्टर सेट अप किया है और प्रतिक्रिया को वापस करने पर इसे 'अनइजेक्ट' किया है।

यह वसंत जार के एमबी (इसके सीखने की अवस्था का उल्लेख नहीं करने के बिना) और बिना किसी गुप्त गूढ़ @annotation बकवास के बिना सभी एक्सएमएल कुरूपता के बिना एक स्मार्ट आदमी की DI है, और यह व्यक्तिगत रूप से कई ऑब्जेक्ट उदाहरणों को इंजेक्ट नहीं करता है निर्भरता यह शायद बहुत तेज़ की बिल्ली है और कम स्मृति का उपयोग करती है।

यह इतनी अच्छी तरह से हम खोला काम किया sourced हमारे exPOJO फ़िल्टर कि एक हाइबरनेट सत्र या एक JDO PersistenceManager इंजेक्षन कर सकते हैं का उपयोग कर ThreadLocal:

http://www.expojo.com