2012-07-20 10 views
8

Flaskを使用してPython Webアプリケーションを作成しています。私のアプリケーションは起動時に別のサーバとの接続を確立し、そのサーバとバックグラウンドで定期的に通信します。Flask/Werkzeugデバッガ、プロセスモデル、初期化コード

Flaskの組み込みデバッガ(debug = Falseでapp.runを呼び出す)を使用しない場合は問題ありません。

私が組み込みデバッガ(debug = Trueでapp.runを呼び出す)を使用すると、Flaskは同じコードを持つ2番目のPythonプロセスを開始します。それは、HTTP接続をリッスンし、アプリケーションが想定しているように動作してしまう子プロセスです。

しかし、これは私の邪魔になります両方のプロセスで実行される起動コード。私は外部サーバへの2つの接続、2つのプロセスは同じログファイルへのロギング、そして一般的には互いの上を移動します。

私はapp.run()を呼び出す前に実際の作業を行うべきではないと考えていますが、この初期化コードはどこに置くべきですか(私はFlaskプロセスグループごとに一度だけ実行します。起動時にクライアント要求とは独立して実行する必要があります)。

私はthis question about "Flask auto-reload and long-running thread"と多少関連していますが、やや異なっており、答えが私を助けませんでした。 (私もデーモンスレッドとしてマークされた別々の長時間実行スレッドを持っていますが、リロードが始まると殺されますが、私が解決しようとしている問題はリロードが起こる前です。 reload;私は余分なプロセスと、親プロセスで不要なコードを実行するのを避ける正しい方法を心配しています)。

+0

この質問(および回答)のおかげで、この1つは私に似たようなことをしようとすると困惑しました。 – akatkinson

答えて

9

この現象はWerkzeugによるものであり、Flaskのものではなく、リローダ。これはWerkzeugのserve.py-in run_simple()で見ることができます。もしuse_reloaderが真であれば、subprocess.call(sys.executable)を実行するヘルパー関数run_with_reloader()/ restart_with_reloader()を使ってmake_serverを呼び出します。サブプロセスによって継承される環境内の環境変数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 

私は感じこれを持っていますWerkzeugがサービスを提供する前に呼び出されたメソッドがある場合は、アプリケーションオブジェクトの内部から行う方がよいでしょう。私はそのような方法を知らない。

これは、Werkzeugのrun_simple.pyでは、最終的にmake_server()。serve_forever()への呼び出しが1つしかありませんが、run_simple()を2回呼び出すことができますその時点まで)make_server()に渡します。

+0

この回答は時代遅れかもしれないと思います。 Flaskに['before_first_request'](http://flask.pocoo.org/docs/0.10/api/#flask.Flask.before_first_request)デコレータが追加されました。 –