misc: add wcs tenant aware cache (#6735)

This commit is contained in:
Frédéric Péters 2017-08-12 16:42:40 +02:00
parent 3e998dff21
commit a0e5a686f6
4 changed files with 77 additions and 0 deletions

8
debian/settings.py vendored
View File

@ -68,6 +68,14 @@ MIDDLEWARE_CLASSES = (
'hobo.middleware.cors.CORSMiddleware',
) + MIDDLEWARE_CLASSES
CACHES = {
'default': {
'BACKEND': 'wcs.cache.WcsTenantCache',
# add a real Django cache backend, with its parameters if needed
'REAL_BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
WCS_LEGACY_CONFIG_FILE = '/etc/wcs/wcs.cfg'
WCS_EXTRA_MODULES = []

View File

@ -22,6 +22,9 @@ from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.backoffice.listing import pagination_links
from wcs.qommon.emails import email as send_email, docutils
from django.core.cache import cache
from utilities import get_app, create_temporary_pub, clean_temporary_pub
def setup_module(module):
@ -296,3 +299,7 @@ def test_email_signature_rst(emails):
assert emails.emails['test']['msg'].get_payload()[1].get_content_type() == 'text/html'
assert 'Footer\nText' in emails.emails['test']['msg'].get_payload()[0].get_payload()
assert '>Footer</div>' in emails.emails['test']['msg'].get_payload()[1].get_payload()
def test_cache():
cache.set('hello', 'world')
assert cache.get('hello') == 'world'

53
wcs/cache.py Normal file
View File

@ -0,0 +1,53 @@
# w.c.s. - web application for online forms
# Copyright (C) 2005-2017 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
from django.core.exceptions import ImproperlyConfigured
from django.utils.module_loading import import_string
from django.core.cache.backends.base import InvalidCacheBackendError
from quixote import get_publisher
class TenantBaseCache(object):
'''Prepend the tenant application directory to the cache prefix'''
def set_key_prefix(self, prefix):
self.__key_prefix = prefix
def get_key_prefix(self):
if get_publisher():
return '%s_%s' % (get_publisher().app_dir, self.__key_prefix)
return self.__key_prefix
key_prefix = property(get_key_prefix, set_key_prefix)
__DERIVED_CLASSES = {}
def WcsTenantCache(host, params, **kwargs):
try:
backend = params['REAL_BACKEND']
except KeyError:
raise ImproperlyConfigured('The %s.WcsTenantCache backend needs a REAL_BACKEND parameter' % __name__)
try:
backend_cls = import_string(backend)
except ImportError as e:
raise InvalidCacheBackendError("Could not find backend '%s': %s" % (backend, e))
derived_cls_name = 'Tenant' + backend_cls.__name__
if derived_cls_name not in __DERIVED_CLASSES:
# dynamically create a new class with TenantBaseCache
# and the original class as parents
__DERIVED_CLASSES[derived_cls_name] = type(derived_cls_name,
(TenantBaseCache, backend_cls), {})
return __DERIVED_CLASSES[derived_cls_name](host, params, **kwargs)

View File

@ -137,6 +137,15 @@ INSTALLED_APPS = (
'django.contrib.staticfiles',
)
CACHES = {
'default': {
'BACKEND': 'wcs.cache.WcsTenantCache',
# add a real Django cache backend, with its parameters if needed
'REAL_BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'wcs',
}
}
WCS_LEGACY_CONFIG_FILE = None
local_settings_file = os.environ.get('WCS_SETTINGS_FILE',