2012-07-20 19 views
8

मैं फ्लास्क का उपयोग कर एक पायथन वेब एप्लिकेशन लिख रहा हूं। मेरा एप्लिकेशन स्टार्टअप पर किसी अन्य सर्वर से कनेक्शन स्थापित करता है, और उस सर्वर के साथ पृष्ठभूमि में समय-समय पर संचार करता है।फ्लास्क/वेर्कजेग डीबगर, प्रक्रिया मॉडल, और प्रारंभिक कोड

यदि मैं फ्लास्क के बिल्टिन डीबगर (डीबग = गलत के साथ app.run invoking) का उपयोग नहीं करता, कोई समस्या नहीं है।

यदि मैं बिल्टिन डीबगर का उपयोग करता हूं (डीबग = ट्रू के साथ app.run invoking), फ्लास्क एक ही कोड के साथ एक दूसरी पायथन प्रक्रिया शुरू करता है। यह बाल प्रक्रिया है जो HTTP कनेक्शन सुनने के लिए समाप्त होती है और आम तौर पर मेरे आवेदन के रूप में व्यवहार कर रही है, और मुझे लगता है कि जब डीबगर में प्रवेश होता है तो माता-पिता इसके ऊपर देखने के लिए वहां होते हैं।

हालांकि, यह मेरे साथ घृणा करता है स्टार्टअप कोड, जो दोनों प्रक्रियाओं में चलता है; मैं बाहरी सर्वर से 2 कनेक्शन, 2 प्रक्रियाओं को एक ही लॉगफाइल पर लॉगिंग के साथ समाप्त करता हूं, और सामान्य रूप से, वे एक-दूसरे पर यात्रा करते हैं।

मुझे लगता है कि मुझे app.run() पर कॉल करने से पहले वास्तविक काम नहीं करना चाहिए, लेकिन मुझे यह प्रारंभिक कोड कहां रखना चाहिए (जिसे मैं केवल फ्लास्क प्रक्रिया समूह के बाद एक बार चलाने के लिए चाहता हूं, डीबगर मोड के बावजूद , लेकिन स्टार्टअप पर और क्लाइंट अनुरोधों से स्वतंत्र होने की आवश्यकता है)?

मुझे this question about "Flask auto-reload and long-running thread" मिला जो कुछ हद तक संबंधित है, लेकिन कुछ अलग है, और उत्तर ने मेरी मदद नहीं की। (मेरे पास एक अलग-अलग लंबे चलने वाले थ्रेड भी हैं जो डिमन थ्रेड के रूप में चिह्नित होते हैं, लेकिन जब रीलोडर में प्रवेश होता है तो यह मारे जाते हैं, लेकिन जिस समस्या को मैं हल करने की कोशिश कर रहा हूं वह किसी भी रीलोड होने से पहले है। मुझे इससे कोई चिंता नहीं है पुनः लोड; मैं अतिरिक्त प्रक्रिया से चिंतित हूं, और मूल प्रक्रिया में अनावश्यक कोड निष्पादित करने से बचने का सही तरीका है।)

+0

इस प्रश्न (और उत्तर) के लिए धन्यवाद, यह मुझे कुछ ऐसा करने की कोशिश करते समय परेशान था। – akatkinson

उत्तर

9

मैंने पुष्टि की है कि यह व्यवहार Werkzeug के कारण है, फ्लास्क उचित नहीं है, और यह पुनः लोडर से संबंधित है । आप इसे werkzeug की service.py में देख सकते हैं - run_simple() में, अगर use_reloader सत्य है, तो यह एक सहायक फ़ंक्शन run_with_reloader()/restart_with_reloader() के माध्यम से make_server को आमंत्रित करता है जो एक subprocess.call (sys.executable) करता है, एक सेट करने के बाद पर्यावरण परिवर्तनीय WERKZEUG_RUN_MAIN पर्यावरण में जो उपप्रोसेसर द्वारा विरासत में प्राप्त किया जाएगा।

मैं एक काफी बदसूरत हैक साथ उसके चारों ओर काम किया: WSGI आवेदन वस्तु बनाने और app.run बुला() से पहले, अपने मुख्य समारोह में, मैं WERKZEUG_RUN_MAIN के लिए देखो:

if use_reloader and not os.environ.get('WERKZEUG_RUN_MAIN'): 
    logger.warning('startup: pid %d is the werkzeug reloader' % os.getpid()) 
else: 
    logger.warning('startup: pid %d is the active werkzeug' % os.getpid() 
    # my real init code is invoked from here 

मैं एक इस भावना है अगर ऑर्गेक्ट ऑब्जेक्ट के अंदर से बेहतर किया जाएगा, तो वर्कज़ुग इसे पेश करने से पहले कहा जाता है। हालांकि, मुझे इस तरह की एक विधि के बारे में पता नहीं है।

यह सब नीचे उबलता है: वर्कज़ुग के run_simple.py में, केवल make_server()। Service_forever() के लिए एक अंतिम कॉल होने जा रहा है, लेकिन run_simple() में दो कॉल हो सकते हैं (और संपूर्ण कॉल स्टैक अप उस बिंदु पर) इससे पहले कि हम इसे make_server() बनाते हैं।

+0

मुझे लगता है कि यह उत्तर पुराना हो सकता है। फ्लास्क में अब एक ''first_first_request'] है (http://flask.pocoo.org/docs/0.10/api/#flask.Flask.before_first_request) सजावटी। –