2011-11-17 5 views
12

Google अनुप्रयोग इंजन में मेरी WebApp2 आवेदन में निम्नलिखित कोड पर विचार करें।अजगर WSGI में समझौता वैश्विक वस्तु दृढ़ता एप्लिकेशन

मैं PHP दुनिया से आ रहा हूं जहां हर अनुरोध एक नया वैश्विक वातावरण था। मैं यहां क्या होने वाला समझता हूं, क्योंकि मैं WebApp2 के लिए wsgi कॉन्फ़िगरेशन का उपयोग कर रहा हूं, पाइथन प्रत्येक अनुरोध पर एक नई प्रक्रिया को नहीं लाता है। अगर मैं एक cgi विन्यास का उपयोग कर रहा था, तो दूसरी ओर, वैश्विक वातावरण हर बार फिर से दृष्टांत हैं, पीएचपी की तरह ...

ऊपर मान लिया जाये कि सही है (यदि नहीं, तो कृपया मुझे सही करें) ...

  1. मैं उन परिदृश्यों को कैसे संभाल सकता हूं जहां मैं एक वैश्विक चर चाहता हूं जो केवल अनुरोध के जीवनकाल के लिए बने रहे? मैं RequestHandler क्लास में एक इंस्टेंस वैरिएबल डाल सकता हूं, लेकिन उपयोगिता मॉड्यूल जैसी चीजों के बारे में क्या है जो मैं आयात करता हूं जो संदेश ऑब्जेक्ट को संग्रहीत करने जैसी चीज़ों के लिए ग्लोबल वर्र्स का उपयोग करता है?
  2. क्या सभी चरों को रीसेट करने के लिए तकनीक या पर्यावरण के पुन: तत्काल को बल देने के लिए कुछ प्रकार की तकनीक है?
  3. क्या वैश्विक वातावरण अनिश्चित काल तक जारी रहता है, या यह किसी बिंदु पर खुद को रीसेट करता है?
  4. क्या इनमें से कोई भी GAE विशिष्ट है, या wsgi वैश्विक दृढ़ता किसी भी सर्वर परिदृश्य में समान कार्य करता है?

संपादित करें:

यहाँ का उपयोग कर का प्रयास है threadlocal:

count = 0 

mydata = threading.local() 
mydata.count = 0 

class MyHandler(webapp2.RequestHandler): 

    def get(self): 

     global count 
     count = count + 1 
     print count 

     mydata.count = mydata.count + 1 
     print mydata.count 

ये भी बढ़ा देते भर का अनुरोध करता है

+0

वहाँ एक विशेष कारण आप डेटासंग्रह के बाहर वैश्विक डाटा स्टोर करने की कोशिश कर रहे हैं है? ऐसा लगता है कि आप जो प्रयास कर रहे हैं वह एक [sharded काउंटर] (http://code.google.com/appengine/articles/sharding_counters.html) के साथ अधिक आसानी से पूरा किया जा सकता है। –

+0

@ केविन- वह गणना चर केवल एक उदाहरण था- मेरा वास्तविक मामला पूरी तरह से कुछ और है - मैं बस एप्लिकेशन डोमेन के भीतर वैश्विक दायरे को समझने की कोशिश कर रहा हूं। – Yarin

+0

संबंधित [क्यों पिलोन थ्रेडिंग.लोकल के बजाय StackedObjectProxies का उपयोग करते हैं?] (Http://stackoverflow.com/q/1686768/95735) –

उत्तर

16

आपकी समझ सही है।आप चर उस अनुरोध की अवधि के लिए जारी रहती है चाहते हैं, तो आप उन्हें वैश्विक बिल्कुल नहीं करना चाहिए - अपने RequestHandler वर्ग, self.var के रूप में पहुँचा पर उन्हें उदाहरण चर बनाते हैं। चूंकि प्रत्येक अनुरोध के लिए एक नया अनुरोध हैडलर तत्काल है, इसलिए आपके चर के बराबर तब तक टिके रहेंगे जब तक आपको उनकी आवश्यकता हो। जब तक आपको वास्तव में वैश्विक (अनुरोध-विशिष्ट के विपरीत) दायरे की आवश्यकता नहीं होती है, तब तक वैश्विक चर से बचा जाता है।

भी ध्यान रखें कि अपने App Engine एप्लिकेशन कई सर्वरों पर चलेंगे; ग्लोबल्स केवल उसी सर्वर के अंदर अनुरोधों के लिए सुलभ हैं।

+3

एकाधिक सर्वरों के बारे में अच्छी बात- धन्यवाद – Yarin

4

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

वैश्विक वैरिएबल बनाने के लिए पूरी तरह से संभव है जो अलग-अलग "प्रति-अनुरोध" है। यह बहुत सारे ढांचे में किया जाता है और लोग इसे पसंद करते हैं। ऐसा करने का तरीका सर्वर पर निर्भर करता है। अधिकांश सर्वर "प्रति थ्रेड प्रति अनुरोध" का उपयोग करते हैं, और मुझे लगता है कि जीएई भी करता है। यदि ऐसा है तो आप threadlocal variable का उपयोग कर सकते हैं। यदि आप इस धागे के अनुरोधों के बीच चिपके हुए इस मूल्य के बारे में चिंतित हैं, तो आपको कुछ प्रबंधन कोड की आवश्यकता होगी जो अनुरोध के प्रारंभ/समाप्ति पर हो सकती है। WSGI मिडलवेयर इसके लिए एक अच्छी जगह है यदि WebApp2 ढांचा इसे करने का एक अच्छा तरीका प्रदान नहीं करता है।

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

वहां कई ढांचे हैं जो पहले से ऐसा करने के लिए अच्छा समर्थन प्रदान करते हैं, इसलिए यदि WebApp2 नहीं है तो मैं कहीं और दिखने का सुझाव दूंगा। पाइथन में बहुत सारे विकल्प हैं और उनमें से कई जीएई पर चलते हैं।

+0

धन्यवाद। क्या आप कृपया मेरे संपादन देख सकते हैं- मैंने थ्रेडिंग.लोकल() की कोशिश की, लेकिन यह मेरी वैश्विक की तरह वृद्धि की गणना करता है। क्या मैं इसे सही तरीके से कार्यान्वित कर रहा हूं? – Yarin

+0

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

2

अपने पहले प्रश्न के मामले में मुझे लगता है कि आप webapp2.Request.registry सुविधा सोच सकते हैं। यह उन उदाहरणों को स्टोर करने का एक नियम है जो अनुरोध के जीवनकाल के दौरान अलग-अलग मॉड्यूल साझा कर सकते हैं।

दूसरी ओर यह भी उपयोगी webapp2.WSGIApplication.registry है। इस मामले में उदाहरणों अनुरोधों के बीच जारी रहती है और जो कुछ भी अपने अनुप्रयोग आपके आवेदन के जीवनकाल के दौरान की जरूरत है, वैश्विक गुंजाइश पर उदाहरणों बनाने से बचने के लिए साझा किया जा सकता है (और पुन: उपयोग)।