Бэкэнд кеша работает на devserver, но не на mod_wsgi - PullRequest
0 голосов
/ 17 февраля 2010

Я использую пользовательский бэкэнд кэша, чтобы обернуть встроенный бэкэнд кэша, чтобы я мог добавить текущий site_id ко всем cache_keys (это полезно для многосайтовой функциональности с одним экземпляром memcached)

к сожалению, он прекрасно работает на встроенном в django devserver, но выдает неприятную ошибку при попытке запустить его на живом сервере с mod_wsgi

Вот трассировка из моего журнала ошибок:

[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'

если я запускаю devserver на той же машине (живой сервер), он работает нормально ... Я могу сделать это без проблем:

$ cd /home/jiaaro/webapps/op_wsgi/myProject
$ python2.5 manage.py runserver

и в отдельной сессии ssh ...

$ wget 127.0.0.1:8000

Страницы обслуживаются правильно, с использованием memcached и действующей базы данных. Есть ли что-то другое в том, как mod_wsgi импортирует модули, о которых я должен знать?

Может быть, что-то о однопроцессной, однопоточной природе devserver?

Я боролся с этим уже несколько дней, любая помощь будет признательна

Дополнительная информация:

  • Общий хостинг Webfaction (centos)
  • Apache 2
  • Python 2.5
  • Django 1.1.1
  • mod_wsgi 2.5
  • MySql 5.0

Подробнее: - Я установил кеш-сервер (и он работает, так как вы можете видеть, как он импортирует правильный модуль в трассировке) - В модуле есть класс "CacheClass":

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)

Декоратор accept_site работает в сочетании с некоторым промежуточным программным обеспечением для определения текущего сайта. Вот они:

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

и 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)

Все это работает, используя devserver, используя те же настройки, что и сервер wsgi и настроенный с тем же путем python (насколько я вижу)

На данный момент я надеюсь, что где-то создал цикл импорта (хотя это не имело бы смысла, поскольку это происходит только в devserver)

edit: Я нашел список различий между devserver и apache в документах django, где написано:

Devserver добавляет установленные приложения в sys.path, Apache - нет.

Может, это как-то связано?

Ответы [ 2 ]

1 голос
/ 17 февраля 2010

Вы установили CACHE_BACKEND в вашем settings.py? Когда DEBUG = True, это не проблема, так как я считаю, что фиктивный бэкэнд установлен, но в работе вам нужно будет установить это значение, предположительно, даже если вы пишете свой собственный бэкэнд.

Документы кеш-сервера

Если это установлено, но у вас все еще есть проблемы, попробуйте переключиться на модуль фиктивного кэша или модуль локальной памяти (даже если это не очень хорошая производственная настройка), чтобы увидеть, работают ли они, и если они есть, вы может отсутствовать пакет в пути Python вашего WSGI, например python-memcached

0 голосов
/ 30 марта 2010

Корень проблемы был sys.path Я должен был убедиться, что у настроенного mod_wsgi был тот же sys.path, что и у сервера dev, и чтобы в местах, к которым они не принадлежали, не осталось лишних копий пакетов (из рефакторинга который не был как-то применен к серверу при управлении версиями)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...