2010-10-06 14 views
6

तो मैं नीचे एक हैंडलर है रहता है, जबकि बनाने:अजगर तूफान - पोस्ट तुरंत लौट async समारोह काम कर

class PublishHandler(BaseHandler): 

    def post(self): 
     message = self.get_argument("message") 
     some_function(message) 
     self.write("success") 

समस्या यह है कि मैं का सामना करना पड़ रहा है कि some_function() निष्पादित करने के लिए कुछ समय लगता है और मैं चाहते हैं कॉल अनुरोध जब तुरंत कॉल किया जाता है और कुछ_फंक्शन() को किसी अन्य थ्रेड/प्रक्रिया में निष्पादित करने के लिए निष्पादित किया जाता है।

मैं डेटाबेस के रूप में बर्कले डीबी का उपयोग कर रहा हूं और जो मैं करने की कोशिश कर रहा हूं वह अपेक्षाकृत सरल है।

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

उत्तर

7

आप का उपयोग करके यह पूरा करने में सक्षम हो सकता अपने IOLoop की तो जैसे add_callback विधि:

loop.add_callback(lambda: some_function(message)) 

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

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

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

यदि आप थ्रेडेड मार्ग पर जा रहे हैं, तो आप एक म्यूटेक्स, थ्रेड और कतार के साथ एक अच्छा "async निष्पादक" मॉड्यूल बना सकते हैं। यदि आप एक अलग प्रक्रिया का उपयोग करने के मार्ग पर जाना चाहते हैं तो multiprocessing मॉड्यूल देखें।

1

मैंने यह कोशिश की है, और मेरा मानना ​​है कि कॉलबैक कहने से पहले अनुरोध पूरा नहीं होता है।

मुझे लगता है कि एक गंदा हैक add_callback के दो स्तर, उदा, कॉल करने के लिए, हो सकता है .:

def get(self): 
    ... 
    def _defered(): 
     ioloop.add_callback(<whatever you want>) 
    ioloop.add_callback(_defered) 
    ... 

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

संबंधित मुद्दे