2009-09-24 16 views
7

तो, मेरे पास एक ऐसा एप्लिकेशन है जो ट्विस्ट + स्टॉम्पर को STOMP क्लाइंट के रूप में उपयोग करता है जो एक मल्टीप्रोसेसिंग के लिए काम करता है। श्रमिकों का पुल।मल्टीप्रोसेसिंग श्रमिकों के साथ ट्विस्ट नेटवर्क क्लाइंट?

# stompclient.py 

logging.config.fileConfig(config_path) 
logger = logging.getLogger(__name__) 

# Add observer to make Twisted log via python 
twisted.python.log.PythonLoggingObserver().start() 

# initialize the process pool. (child processes get forked off immediately) 
pool = multiprocessing.Pool(processes=processes) 

StompClientFactory.username = username 
StompClientFactory.password = password 
StompClientFactory.destination = destination 
reactor.connectTCP(host, port, StompClientFactory()) 
reactor.run() 

इस हो जाता तैनाती के लिए पैक, मैंने सोचा कि मैं लाभ ले जाएगा के रूप में:

यह ठीक काम करने के लिए जब मैं सिर्फ इस आग है, जो (सरलीकृत) एक अजगर स्क्रिप्ट का उपयोग प्रतीत होता है कुछ इस तरह दिखता ट्विस्टेड स्क्रिप्ट का और इसे एक टैक फ़ाइल से चलाएं।

यहाँ मेरी बहुत-समान दिखने वाले टैक फ़ाइल है:

# stompclient.tac 

logging.config.fileConfig(config_path) 
logger = logging.getLogger(__name__) 

# Add observer to make Twisted log via python 
twisted.python.log.PythonLoggingObserver().start() 

# initialize the process pool. (child processes get forked off immediately) 
pool = multiprocessing.Pool(processes=processes) 

StompClientFactory.username = username 
StompClientFactory.password = password 
StompClientFactory.destination = destination 

application = service.Application('myapp') 

service = internet.TCPClient(host, port, StompClientFactory()) 
service.setServiceParent(application) 

चित्रण के लिए, मैं संक्षिप्त या कुछ विवरण बदल गए हैं; उम्मीद है कि वे समस्या का सार नहीं थे। उदाहरण के लिए, मेरे ऐप में एक प्लगइन सिस्टम है, पूल को एक अलग विधि द्वारा शुरू किया जाता है, और उसके बाद पूल को मेरी प्लगइन की प्रक्रिया() विधियों में से एक को पूल.apply_async() का उपयोग करके पूल में सौंप दिया जाता है।

इसलिए, यदि मैं स्क्रिप्ट चलाता हूं (stompclient.py), सब कुछ अपेक्षित काम करता है।

यह भी ठीक काम करने के लिए अगर मैं गैर डेमॉन मोड में मोड़ (-n) चलाने प्रकट होता है:

twistd -noy stompclient.tac 

तथापि, यह नहीं काम करता है जब मैं डेमॉन मोड में चलाएँ:

twistd -oy stompclient.tac 

एप्लिकेशन ठीक शुरू होता प्रतीत होता है, लेकिन जब यह काम बंद करने का प्रयास करता है, तो यह बस लटकता है। "लटकता" से मेरा मतलब है कि ऐसा लगता है कि बच्चे की प्रक्रिया को कभी भी कुछ करने के लिए नहीं कहा जाता है और माता-पिता (जिसे pool.apply_async() कहा जाता है) बस लौटने की प्रतिक्रिया के लिए इंतजार कर बैठता है।

मुझे यकीन है कि मैं ट्विस्ट + मल्टीप्रोसेसिंग के साथ कुछ बेवकूफ कर रहा हूं, लेकिन मैं वास्तव में उम्मीद कर रहा हूं कि कोई मेरे दृष्टिकोण में मेरी गलती को समझा सकता है।

अग्रिम धन्यवाद!

उत्तर

12

चूंकि आपके कामकाजी आमंत्रण और आपके गैर-कामकाजी आमंत्रण के बीच का अंतर केवल "-n" विकल्प है, ऐसा लगता है कि समस्या डिमोनिज़ेशन प्रक्रिया (जो "-n" होने से रोकती है) के कारण होती है।

POSIX पर, डिमोनिज़ेशन में शामिल चरणों में से एक फोर्किंग और माता-पिता से बाहर निकलना है। चीजों में से, इसका परिणाम आपके कोड को एक अलग प्रक्रिया में चलाने के परिणामस्वरूप है जिसमें .tac फ़ाइल का मूल्यांकन किया गया था। यह प्रक्रियाओं के बच्चे/अभिभावक संबंधों को फिर से व्यवस्थित करता है जो .tac फ़ाइल में शुरू किए गए थे - क्योंकि मल्टीप्रोसेसिंग प्रक्रियाओं का आपका पूल था।

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

सौभाग्य से, इस अजीब बातचीत से परहेज करना सरल होना चाहिए। ट्विस्ट की सेवा एपीआई आपको डिमोनेशन पूरा होने के बाद कोड चलाने की अनुमति देती है। यदि आप इन एपीआई का उपयोग करते हैं, तो आप मल्टीप्रोसेसिंग मॉड्यूल के प्रोसेस पूल की शुरुआत को देरीकरण के बाद तक देरी कर सकते हैं और उम्मीद से समस्या से बच सकते हैं। यहां उसका दिखाई देती हैं इसका एक उदाहरण है:

from twisted.application.service import Service 

class MultiprocessingService(Service): 
    def startService(self): 
     self.pool = multiprocessing.Pool(processes=processes) 

MultiprocessingService().setServiceParent(application) 

अब, अलग से, आप भी बहु मॉड्यूल के बच्चे प्रक्रियाओं की सफाई से संबंधित समस्या में पड़ सकते हैं, या संभवतः मुड़ की प्रक्रिया निर्माण API के साथ बनाया प्रक्रियाओं के साथ मुद्दों, reactor.spawnProcess। ऐसा इसलिए है क्योंकि बाल प्रक्रियाओं से निपटने का हिस्सा आमतौर पर सिगचल सिग्नल को संभालने में शामिल होता है। ट्विस्ट और मल्टीप्रोसेसिंग इस संबंध में सहयोग नहीं करने जा रहे हैं, हालांकि, उनमें से एक को बाहर निकलने वाले सभी बच्चों की अधिसूचना प्राप्त करने जा रही है और अन्य को कभी भी अधिसूचित नहीं किया जाएगा। यदि आप बाल प्रक्रियाओं को बनाने के लिए ट्विस्टेड एपीआई का उपयोग नहीं करते हैं, तो यह आपके लिए ठीक हो सकता है - लेकिन आप यह सुनिश्चित करने के लिए जांच सकते हैं कि कोई भी सिग्नल हैंडलर मल्टीप्रोसेसिंग मॉड्यूल वास्तव में "जीत" स्थापित करने का प्रयास करता है और प्राप्त नहीं करता है ट्विस्ट के अपने हैंडलर द्वारा प्रतिस्थापित किया गया।

+2

यह * बेहद उपयोगी था। धन्यवाद! –

0

आप के लिए एक संभावित विचार ...

जब डेमॉन मोड twistd stdin, stdout और stderr बंद हो जाएगा में चल रहा है। क्या ऐसा कुछ करता है जो आपके क्लाइंट इन्हें पढ़ते या लिखते हैं?

+0

उन लोगों को कुछ भी लिखना नहीं चाहिए (और मेरा लॉगिंग सभी syslog पर जा रहा है) लेकिन मुझे आश्चर्य है कि शायद कुछ निम्न-स्तरीय त्रुटि stderr पर जाने का प्रयास कर रही है। यह चुप्पी में डीबग करने की कोशिश कर निराशाजनक हो सकता है :) –

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