2010-02-17 2 views
0

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?

Répondre

0

la racine du problème était sys.path je devais assurer que le mod_wsgi mis en place avait le même sys.path que le serveur dev et que aucune copie supplémentaire des paquets n'a été laissée dans des endroits où ils ne sont pas apparus (du refactoring qui n'a pas été appliqué au serveur par le contrôle de version en quelque sorte)

1

Avez-vous défini CACHE_BACKEND dans votre settings.py? Lorsque DEBUG = True, ce n'est pas un problème, car je crois qu'un backend fictif est installé, mais en production, vous devrez définir cette valeur, même si vous écrivez votre propre backend.

cache backend docs

Si ce n'est réglé et que vous êtes toujours avoir des problèmes, essayez de passer au module de cache factice ou une mémoire locale (même si ce n'est pas une bonne configuration de production) pour voir si les travaux, et si elles le font, vous pouvez manquer un paquet dans votre chemin de python de WSGI comme python-memcached

+0

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

Questions connexes