リクエストの前と後の両方で、URL を完全に動的に制御する必要があるシステムがあります。
私はこれにシグナルを使用しており、リクエスト前のシグナルにシグナルを使用しています(私が問題を抱えているシグナルには、シグナルに接続するこのようなミドルウェアがあり、現在の request.path が適用されるかどうかを確認できますこれは通常は問題なく動作し、かなりエレガントです):
class PreRouteMiddleWare(object):
def process_request(self, request):
url = request.path.strip('/')
if url == '':
url = '/'
pre_routes = pre_route.send(sender=request, url=url)
for reciever, response in pre_routes:
if response:
return response
return None
ここで、Django ルーティング スタックの「前」に発生することを登録するには、アプリの で次のようにしますmodels.py
。
@receiver(pre_route)
def try_things(sender, url, **kwargs):
try:
thing= Thing.objects.get(url=url)
from myapp.views import myview
return myview(sender, some_args)
except Thing.DoesNotExist:
return False
これは、私の開発サーバーでもうまく機能します。
ただし、uWSGIを使用する本番環境で問題が発生します。次のように(upstartから)uWSGIを開始します。
sudo /usr/local/bin/uwsgi --emperor '/srv/*/uwsgi.ini' --enable-threads --single-interpreter
そして、私の uwsgi.ini は次のようになります。
[uwsgi]
socket = /srv/new/uwsgi.sock
module = wsgi:app
chdir = /srv/new/myapp
virtualenv = /srv/new
env = DJANGO_SETTINGS_MODULE=myapp.settings
uid = wsgi_new
gid = www-data
chmod = 770
processes = 2
発生しているように見えるのは、uWSGI プロセス/スレッドごとに、最初のリクエストで models.py をロードするだけのようです。つまり、各プロセスの最初のリクエストはシグナルの接続に失敗します。これは、models.py が起動時に (開発中のように) ロードされないため、n (n はプロセスの数) のリクエストが完全に失敗することを意味します。
uWSGI の設定が間違っていますか? 起動時に信号を強制的に接続するより良い方法はありますか?