FlaskのuWSGI + django autoreloadモードのようなものを探しています。
7 に答える
uwsgi バージョン 1.9.5 とオプションを実行しています
uwsgi --py-autoreload 1
よく働く
uwsgi
コマンド引数で構成している場合は、次を渡し--py-autoreload=1
ます。
uwsgi --py-autoreload=1
.ini
ファイルを使用して構成uwsgi
し、 を使用している場合は、次をファイルuwsgi --ini
に追加します。.ini
py-autoreload = 1
開発環境では、 --python-autoreload uwsgi のパラメーターを使用して試すことができます。ソース コードを見ると、スレッド モード (--enable-threads) でのみ機能する可能性があります。
Uwsgi アプリのマネージャーとして Supervisord を使用してみてください。また、ファイルまたはフォルダーが「タッチ」/変更されたときにプロセスを自動リロードする監視機能もあります。
ここで素晴らしいチュートリアルを見つけることができます: Flask+NginX+Uwsgi+Supervisord
開発モードの Flask の自動リロード機能は、実際には基礎となる Werkzeug ライブラリによって提供されます。関連するコードが含まれwerkzeug/serving.py
ています。一見の価値があります。しかし、基本的には、メイン アプリケーションは WSGI サーバーをサブプロセスとして生成し、.py
1 秒に 1 回、すべてのアクティブなファイルを統計して変更を探します。サブプロセスが見つかった場合は、サブプロセスが終了し、親プロセスがサブプロセスを再開します。これにより、変更が再ロードされます。
uWSGI のレイヤーで同様の手法を実装できない理由はありません。stat ループを使用したくない場合は、基になる OS の file-watch コマンドを使用してみてください。どうやら (Werkzeug のコードによると)、pyinotifyにはバグがありますが、 Watchdogは動作するのでしょうか? いくつか試してみて、どうなるか見てみましょう。
編集:
コメントに応えて、これを再実装するのはかなり簡単だと思います。リンクから提供された例に基づいて、次のコードとともに構築しますwerkzeug/serving.py
。
""" NOTE: _iter_module_files() and check_for_modifications() are both
copied from Werkzeug code. Include appropriate attribution if
actually used in a project. """
import uwsgi
from uwsgidecorators import timer
import sys
import os
def _iter_module_files():
for module in sys.modules.values():
filename = getattr(module, '__file__', None)
if filename:
old = None
while not os.path.isfile(filename):
old = filename
filename = os.path.dirname(filename)
if filename == old:
break
else:
if filename[-4:] in ('.pyc', '.pyo'):
filename = filename[:-1]
yield filename
@timer(3)
def check_for_modifications():
# Function-static variable... you could make this global, or whatever
mtimes = check_for_modifications.mtimes
for filename in _iter_module_files():
try:
mtime = os.stat(filename).st_mtime
except OSError:
continue
old_time = mtimes.get(filename)
if old_time is None:
mtimes[filename] = mtime
continue
elif mtime > old_time:
uwsgi.reload()
return
check_for_modifications.mtimes = {} # init static
テストされていませんが、動作するはずです。
import gevent.wsgi
import werkzeug.serving
@werkzeug.serving.run_with_reloader
def runServer():
gevent.wsgi.WSGIServer(('', 5000), app).serve_forever()
(任意の WSGI サーバーを使用できます)
残念ながら、Flask は、このような実装をデフォルトでバンドルするにはあまりにも単純すぎると思います。
本番環境でコードを動的にリロードすることは一般的に悪いことですが、開発環境について懸念がある場合は、この bash シェル スクリプトを参照してください http://aplawrence.com/Unixart/watchdir.html
スリープ間隔を必要に応じて変更し、echo コマンドを uwsgi のリロードに使用するものに置き換えます。uwsgi un master モードを実行し、killall uwsgi コマンドを送信するだけです。