2016-02-12 11 views
5

के साथ लंबे समय से चलने वाले कार्य मुझे लगता है कि हर कोई जानता है कि django में लंबे समय से चलने वाले कार्यों के साथ क्या करना है: अजवाइन का उपयोग करें और आराम करें। लेकिन क्या होगा यदि मैं aiohttp (या टर्ननाडो) के साथ websockets के लाभ प्राप्त करना चाहता हूं?एसिंक सर्वर

मान लें कि मेरे पास बहुत सी CPU बाध्य कार्य है जो एकाधिक (5-10) मिनट तक कुछ सेकंड से ले सकता है। यह वेबस्क्रिप्ट लूप में इस कार्य को संभालने और प्रगति के बारे में उपयोगकर्ता को सूचित करने के लिए बहुत अच्छा विचार दिखता है। कोई AJAX अनुरोध नहीं, छोटे कार्यों के लिए बहुत तेज़ प्रतिक्रिया।

async def websocket_handler(request): 
    ws = web.WebSocketResponse() 
    await ws.prepare(request) 

    async for msg in ws: 
     if msg.tp == aiohttp.MsgType.text:  
      answer_to_the_ultimate_question_of_life_the_universe_and_everything =\ 
       long_running_task(msg.data, NotificationHelper(ws)) 
      ws.send_str(json.dumps({ 
       'action': 'got-answer', 
       'data': answer_to_the_ultimate_question_of_life_the_universe_and_everything, 
      })) 
    return ws 

लेकिन दूसरी तरफ, सीपीयू-बाध्य कार्य इस तरह से कार्य करता है जैसा कि मैं समझता हूं। यदि मेरे पास 10 कर्मचारी और 11 ग्राहक हैं जो आवेदन का उपयोग करना चाहते हैं, तो 11 वें ग्राहक को तब तक सेवा नहीं दी जाएगी जब तक कि पहले ग्राहक का कार्य नहीं किया जाता।

हो सकता है, मैं कार्यों जो अजवाइन में बड़ा देखने के लिए और कार्य जो मुख्य पाश में छोटे देखने चलाना चाहिए?

तो, मेरा प्रश्न: क्या एसिंक सर्वर के साथ लंबे समय से चलने वाले कार्यों की सेवा के लिए कोई अच्छा डिज़ाइन पैटर्न है?

धन्यवाद!

+0

'asyncio' आपको सीपीयू-बाध्य कार्यों के साथ मदद नहीं करेगा। – dirn

+0

@dirn यह केवल आईओ-बाध्य कार्यों और सर्वर के साथ विभिन्न प्रकार की बातचीत के लिए अच्छा है? – dmitry

+1

वैसे एसिंसिओ मदद कर सकता है, यदि यह कार्य अलग थ्रेड में होस्ट किया गया है (या वास्तव में अजीब के लिए उपज या उपप्रजाय के साथ हरा धागा) तो यह आजीविका है। Obv।, चिंताएं हैं - डब्ल्यूएस कनेक्शन क्या मर जाता है? क्या डेटा रेस हो सकती है? "संसाधनों से वास्तव में अधिक अनुरोध" के बारे में क्या - 503/कतार/ब्लॉक/त्रुटि? –

उत्तर

7

बस अपने लंबे समय से चल रहे CPU- बाध्य कार्य को loop.run_in_executor() पर चलाएं और loop.call_soon_threadsafe() द्वारा प्रगति अधिसूचनाएं भेजें।

यदि आपका काम सीपीयू नहीं है लेकिन आईओ बाध्य है (उदाहरण के लिए ईमेल भेजना) तो आप loop.create_task() कॉल द्वारा एक नया कार्य बना सकते हैं। ऐसा लगता है कि नया धागा फैल रहा है।

यदि आप अग्नि-और-भूल दृष्टिकोण का उपयोग नहीं कर सकते हैं तो आपको लगातार संदेश ब्रोकर का उपयोग करने की आवश्यकता है जैसे कि RabbitMQ (https://github.com/benjamin-hodgson/asynqp पुस्तकालय एसिन्सीओ तरीके से खरगोश के साथ संवाद करने के लिए)।