2012-06-19 55 views
1

我有一個系統,我需要在請求之前和之後完全動態控制URL。Models.py在uWSGI啓動時未加載

我正在使用這個信號,並且對於預先請求信號(我遇到問題的那個,我有一塊這樣的中間件,它連接到信號,允許它檢查當前Request的適用於它,然後與第一個它會去這通常工作正常,並且是相當優雅):

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。我開始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,這意味着每個進程的第一個請求將無法連接信號。這意味着我有n(其中n是進程數)請求完全失敗,因爲models.py在啓動時未加載(因爲它在開發中)。

我配置uWSGI錯了嗎?有沒有更好的方式來強制信號在啓動時連接?

回答

3

Django實際上懶惰地加載的東西。使用開發服務器會給WSGI服務器上的工作方式帶來虛假的安全感,因爲開發服務器加載的管理命令會強制執行很多早期的初始化操作,這與生產服務器不同。

您可能是:

http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

,因爲它在發生的mod_wsgi這說明了問題。 uWSGI也會發生同樣的事情。

0

好吧,事實證明,我需要讓我的中間件鉤process_view而不是process_request:

class PreRouteMiddleWare(object): 
    def process_view(self, request, *args, **kwargs): 
     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 

而現在它的偉大工程!