ফ্লাস্ক ডেভ সার্ভারটি চালানো কেন দু'বার নিজেকে চালিত করে?


111

আমি একটি ওয়েবসাইট বিকাশের জন্য ফ্লাস্ক ব্যবহার করছি এবং বিকাশের সময় আমি নিম্নলিখিত ফাইলটি ব্যবহার করে ফ্লাস্ক চালাচ্ছি:

#!/usr/bin/env python
from datetime import datetime
from app import app
import config

if __name__ == '__main__':
    print '################### Restarting @', datetime.utcnow(), '###################'
    app.run(port=4004, debug=config.DEBUG, host='0.0.0.0')

আমি যখন সার্ভারটি শুরু করি, বা ফাইল আপডেট হওয়ার কারণে এটি যখন স্বয়ংক্রিয়ভাবে পুনঃসূচনা হয় তখন এটি সর্বদা দু'বার মুদ্রণ লাইনটি দেখায়:

################### Restarting @ 2014-08-26 10:51:49.167062 ###################
################### Restarting @ 2014-08-26 10:51:49.607096 ###################

যদিও এটি আসলে কোনও সমস্যা নয় (বাকিরা প্রত্যাশার মতো কাজ করে) তবে আমি কেবল আশ্চর্য হই যে কেন এটি এরকম আচরণ করে? কোন ধারনা?

উত্তর:


162

ওয়ার্কজেগ রিলোডার একটি শিশু প্রক্রিয়া তৈরি করে যাতে এটি প্রতিটি সময় আপনার কোড পরিবর্তিত হলে সেই প্রক্রিয়াটি পুনরায় চালু করতে পারে। ওয়ার্কজেগ হ'ল লাইব্রেরি যা আপনি কল করার সময় বিকাশ সার্ভারের সাথে ফ্লাস্ক সরবরাহ করে app.run()

দেখুন restart_with_reloader()ফাংশন কোড ; আপনার স্ক্রিপ্টটি চালানো হয় আবার সঙ্গে subprocess.call()

যদি আপনি সেট use_reloaderকরে থাকেন তবে Falseদেখবেন আচরণটি দূরে চলেছে, তবে তারপরে আপনি পুনরায় লোডিং কার্যকারিতাও হারাবেন:

app.run(port=4004, debug=config.DEBUG, host='0.0.0.0', use_reloader=False)

flask runকমান্ডটি ব্যবহার করার সময় আপনি পুনরায় লোডারটি অক্ষম করতে পারেন :

FLASK_DEBUG=1 flask run --no-reload

আপনি WERKZEUG_RUN_MAINযখন রিলোডিং চাইল্ড প্রসেসে আছেন তখন আপনি যদি সনাক্ত করতে চান তবে আপনি পরিবেশের পরিবর্তনশীলটি সন্ধান করতে পারেন :

import os
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
    print '################### Restarting @ {} ###################'.format(
        datetime.utcnow())

যাইহোক, আপনি মডিউল globals সেট আপ করার প্রয়োজন হয়, তাহলে আপনি যদি এর পরিবর্তে ব্যবহার করা উচিত @app.before_first_requestপ্রসাধক একটি ফাংশন উপর এবং যে ফাংশন সেট যেমন globals আপ আছে। প্রথম অনুরোধটি আসার পরে এটিকে প্রতিটি পুনরায় লোডের পরে একবার বলা হবে:

@app.before_first_request
def before_first_request():
    print '########### Restarted, first request @ {} ############'.format(
        datetime.utcnow())

বিবেচনায় রাখবেন না যে আপনি যদি একটি পূর্ণ-স্কেল ডাব্লুএসজিআই সার্ভারে চালনা করেন যা অনুরোধগুলি before_first_requestপরিচালনা করতে কাঁটাচামচ বা নতুন সাবপ্রসেসগুলি ব্যবহার করে, তবে হ্যান্ডলারগুলি প্রতিটি নতুন উপ-প্রসেসের জন্য অনুরোধ করতে পারে।


4
আহ, ঠিক আছে. ব্যাখ্যার জন্য ধন্যবাদ! সুতরাং এটি সাধারণ আচরণ হিসাবে বিবেচিত? কমপক্ষে ভাল যা আমার কোডে কোনও ভুল নেই .. :)
kramer65

4
@ ক্রেমার 65: এটি সম্পূর্ণ স্বাভাবিক এবং প্রত্যাশিত আচরণ। :-)
Martijn Pieters

4
স্লো ইনিশিয়েশন কোডটি একবার চালানোর কি কোনও ব্যবহারিক উপায় আছে তা নিশ্চিত করে, ডাব্লুএসজি (যেমন। না app.run) এর অধীনে চলার সময়ও এটি কল হয়ে যায় , তবে প্রথম অনুরোধটির জন্য অপেক্ষা না করে? আমি চাই না যে প্রথম অনুরোধটি আরম্ভের ব্যয় নিয়ে বোঝা হোক।
কাইলোটন

4
@ কাইলোটান: আপনাকে পরিবেশটি পরীক্ষা করতে হবে; আপনি যদি বিকাশে চলতে থাকে কেবল তখনই DEBUG সেট করে থাকেন, আপনি WERKZEUG_RUN_MAINপরিবেশের পরিবর্তনশীল সন্ধান করতে পারেন এবং যখন আপনার কোডটি DEBUGমিথ্যা বা WERKZEUG_RUN_MAINসেট করা থাকে কেবল তখনই চালাতে পারেন , উদাহরণস্বরূপ। কিছুটা ক্লান্তিকর হয়ে ওঠে।
মার্টিজন পিটারস

কেবল পরিষ্কার করার জন্যই, আমি ভেবেছিলাম "পুনরায় লোডিং কার্যকারিতা" মানে প্রতিক্রিয়াশীলতা (যা dashআমার জন্য ব্যবহারের পুরো উদ্দেশ্যকে পরাস্ত করবে )। noobsআমার মতো অন্য যে কোনও ব্যক্তির জন্য , এর অর্থ কেবলমাত্র কার্যকারিতা যেখানে ফাইল সম্পাদনা / সংরক্ষণ একটি লাইভ আপডেট শুরু করে।
হেন্ডি

13

আপনি যদি আধুনিক flask runকমান্ড ব্যবহার করছেন তবে বিকল্পগুলির মধ্যে কোনওটিই app.runব্যবহার করা হবে না। পুনরায় লোডার সম্পূর্ণরূপে অক্ষম করতে, পাস করুন --no-reload:

FLASK_DEBUG=1 flask run --no-reload

এছাড়াও, __name__ == '__main__'কখনই সত্য হবে না কারণ অ্যাপ্লিকেশনটি সরাসরি চালানো হয়নি। ব্লক ব্যতীত মার্তিজানের উত্তর থেকে একই ধারণা ব্যবহার করুন __main__

if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
    # do something only once, before the reloader

if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
    # do something each reload

8

আমার একই সমস্যা ছিল এবং আমি সেট app.debugকরে এটি সমাধান করেছি False। এটি সেট করা Trueআমার __name__ == "__main__"দু'বার কল করার কারণ ছিল ।


আমার __main__এখনও উভয় সঙ্গে দুইবার রান app.debug = Falseএবং app.run_server(debug=False)। আপনি কি নিশ্চিত যে এটি এটি আপনার জন্য করেছে বা চেষ্টা করার জন্য আপনি কিছু প্রজননযোগ্য কোড পোস্ট করতে পারেন?
হেন্ডি

অ্যাপ্লিকেশন পরিবর্তন করা.দেবগ আমার জন্য এটি সমাধান করার জন্য আমি সবই করেছি। আপনি কি নিশ্চিত করতে পারবেন যে ফ্ল্যাশ সার্ভারটি শুরু হওয়ার পরে কেবল দুটিই চলমান? ন্যূনতম কাজের উদাহরণ চালনার চেষ্টা করুন এবং দেখুন সমস্যাটি ঘটে কিনা। এমন একটি ন্যূনতম উদাহরণ চালানোর চেষ্টা করুন যা একাধিক অজগর সংস্করণে ব্যর্থ হয়, এটি একটি সমস্যা হতে পারে। আমি তখন থেকে আমার প্রকল্পটি অজগর এবং ফ্লাস্কের পরিবর্তে জাভা এবং স্পার্ক জাভাতে স্থানান্তরিত করেছি, সুতরাং সমস্যাটি ঠিক কী ঠিক করেছিল তা আমার মনে নেই।
কারভেল ওয়েকম্যান

আমি এর flaskমাধ্যমে ব্যবহার করছি plotly dashএবং তারা সন্ধান করেছে যে তারা সম্প্রতি পাস করা ডিফল্ট debug যুক্তিটি পরিবর্তন করেছেflask । আমি অনুমান করতে যাচ্ছি যে আমি উপরে ভুল করেছিলাম এবং সম্ভবত করেছি app.debug=False(যা সম্ভবত ডিফল্ট অর্গগুলি দ্বারা আবৃত হয় run_server), বা কেবল পাশ Trueনা করেই চেষ্টা করা হয়েছে, উপরে বর্ণিতভাবে সুস্পষ্টভাবে সেট করা হয়নি not এটি এখন আমার জন্য সঠিকভাবে কাজ করছে (এটি নিশ্চিত করে debug=False)। ধন্যবাদ!
হেন্ডি

2

ফ্লাস্ক 0.11 থেকে এটি flask runপরিবর্তে আপনার অ্যাপ্লিকেশন চালানোর পরামর্শ দেওয়া হচ্ছে python application.py। পরেরটি ব্যবহারের ফলে আপনার কোডটি দুবার চালানো হতে পারে।

এখানে যেমন বলা হয়েছে :

... ফ্লাস্ক 0.11 এর পরে ফ্লাস্ক পদ্ধতিটি সুপারিশ করা হয়। এর কারণ হ'ল পুনরায় লোড প্রক্রিয়াটি কীভাবে কাজ করে তার জন্য কিছু উদ্ভট পার্শ্ব-প্রতিক্রিয়া রয়েছে (যেমন নির্দিষ্ট কোডটি দু'বার কার্যকর করা ...)


0

ফ্লাস্ক অ্যাপ্লিকেশনটি নিজেকে দুবার চালানোর সম্ভাব্য কারণগুলির মধ্যে একটি WEB_CONCURRENCYহেরোকুতে সেটিংসের কনফিগারেশন । একটিতে সেট করতে, আপনি কনসোলে লিখতে পারেন heroku config:set WEB_CONCURRENCY=1


-1

আমারও একই প্রশ্ন ছিল. আমি আমার প্রধানটি সংশোধন করে এবং এর মধ্যে ব্যবহার_রলোডার = মিথ্যা byোকানোর মাধ্যমে সমাধান করেছি। যদি কোনও সংস্থা এখানে এই সমস্যার জন্য কোনও সমাধানের সন্ধান করছে তবে নীচের কোডটি আপনাকে শুরু করবে, তবে আপনি কোডের পরিবর্তনগুলির কার্যকারিতাটি স্বয়ংক্রিয়ভাবে সনাক্ত হওয়ার পরে এবং অ্যাপ্লিকেশনটি পুনরায় চালু করার ফলে কাজ করবে না। কোডটিতে প্রতিটি সম্পাদনার পরে আপনাকে ম্যানুয়ালি আপনার অ্যাপ্লিকেশনটি থামাতে হবে এবং পুনরায় চালু করতে হবে।

if __name__ == '__main__':
    app.run(debug=True, use_reloader=False)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.