J'utilise un backend de cache personnalisé pour envelopper les backends de cache intégrés afin que je puisse ajouter le site_id actuel à tous les cache_keys (ceci est utile pour les fonctionnalités multi-sites avec un seul par exemple memcached)Le backend cache fonctionne sur devserver mais pas sur mod_wsgi
malheureusement, il fonctionne très bien sur le django intégré devserver, mais donner une erreur désagréable lorsque je tente de l'exécuter sur le serveur en temps réel avec mod_wsgi
Voici le retraçage de mon journal d'erreur:
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] mod_wsgi (pid=22933): Exception occurred processing WSGI script '/home/jiaaro/webapps/op_wsgi/myProject/deploy/myProject.wsgi'.
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] Traceback (most recent call last):
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/handlers/wsgi.py", line 230, in __call__
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] self.load_middleware()
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/handlers/base.py", line 40, in load_middleware
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] mod = import_module(mw_module)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/utils/importlib.py", line 35, in import_module
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] __import__(name)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/myProject/apps/site_settings/__init__.py", line 6, in <module>
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] import cache_wrapper
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/myProject/apps/site_settings/cache_wrapper.py", line 4, in <module>
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] from django.core.cache.backends.base import BaseCache
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/cache/__init__.py", line 73, in <module>
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] cache = get_cache(settings.CACHE_BACKEND)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] File "/home/jiaaro/webapps/op_wsgi/lib/python2.5/django/core/cache/__init__.py", line 68, in get_cache
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] return getattr(module, 'CacheClass')(host, params)
[Wed Feb 17 00:39:34 2010] [error] [client 127.0.0.1] AttributeError: 'module' object has no attribute 'CacheClass'
si je cours la devserver sur la même machine (le serveur live), il fonctionne très bien ... Je suis en mesure de le faire sans problème:
$ cd /home/jiaaro/webapps/op_wsgi/myProject
$ python2.5 manage.py runserver
et dans une session ssh séparée ...
$ wget 127.0.0.1:8000
Le les pages sont correctement servies, en utilisant memcached, et la base de données en direct. Y at-il quelque chose de différent dans la façon dont mod_wsgi importe les modules que je devrais connaître?
peut-être quelque chose à propos de la nature mono-thread mono-processus du devserver?
Je me bats avec ce depuis plusieurs jours, toute aide serait appréciée
Extra info:
- webfaction hébergement mutualisé (CentOS)
- Apache 2
- Python 2.5
- Django 1.1.1
- mod_wsgi 2.5
- MySql 5.0
Plus de détails: - J'ai mis le backend de cache (et il fonctionne puisque vous pouvez le voir importer le module correct dans le retraçage) - Il y a une classe appelée « CacheClass » dans le Module:
site_settings/cache_wrapper.py:
from django.conf import settings
CACHE_BACKEND = getattr(settings, 'CUSTOM_CACHE_BACKEND')
from django.core.cache.backends.base import BaseCache
class CacheClass(BaseCache):
from decorators import accept_site
def __init__(self, *args):
from django.core.cache import get_cache
self.WRAPPED_CACHE = get_cache(CACHE_BACKEND)
@accept_site
def add(self, site, key, *args):
return self.WRAPPED_CACHE.add(self._key(site, key),*args)
@accept_site
def get(self, site, key, *args):
return self.WRAPPED_CACHE.get(self._key(site, key),*args)
... (all the rest of the wrapped methods)
def _key(self, site, key):
from exceptions import NoCurrentSite
if not site:
raise NoCurrentSite
return "%s|%s" % (site.id, key)
le décorateur accept_site travaille en collaboration avec certains middleware pour trouver le site actuel. Ici, ils sont:
decorators.py:
def accept_site(fn):
def decorator(self, *args, **kwargs):
site = kwargs.get('site', None)
try:
del kwargs['site']
except KeyError:
pass
from .middleware import get_current_site
site = site or get_current_site()
if not site:
raise NoCurrentSite("The current site is not available via thread locals, please specify a site with the 'site' keyword argument")
return fn(self, site, *args, **kwargs)
return decorator
et le middleware.py
try:
from threading import local
except ImportError:
from django.utils._threading_local import local
from django.conf import settings
from django.contrib.sites.models import Site
DEFAULT_SITE_ID = 1
_thread_locals = local()
def get_current_site():
return getattr(_thread_locals, 'site', None)
def set_current_site(site):
setattr(_thread_locals, 'site', site)
class SiteSettings(object):
"""Middleware that gets various objects from the
request object and saves them in thread local storage."""
def process_request(self, request):
if settings.DEBUG:
site_id = request.GET.get('site_id', DEFAULT_SITE_ID)
else:
site_id = DEFAULT_SITE_ID
current_site_domain = request.META["HTTP_HOST"]
try:
current_site = Site.objects.get(domain__iexact=current_site_domain())
except:
current_site = Site.objects.get(id=site_id)
set_current_site(current_site)
Tout cela fonctionne à l'aide du devserver, en utilisant les mêmes paramètres que le serveur wsgi et configuré avec le même chemin de python (pour autant que je peux voir)
À ce stade, j'espère J'ai créé une boucle d'importation quelque part (si ce ne serait pas logique que cela ne se produit que dans le devserver)
modifier: J'ai trouvé un list of the differences between devserver and apache dans les django docs qui dit,
Devserver ajoute les applications installées à sys.path, mais pas Apache.
Peut-être que cela a quelque chose à voir avec cela?
J'ai mis le backend de cache - en fait ... mon backend de cache personnalisé a été utilisé pour fonctionner avant que je l'ai refactorisé à un module différent – Jiaaro