Fixed #6791: added a write-through cache session backend: session data is written through the cache to the database, but read from the cache for speed. Thanks to jhenry, mcroydon, and jdunck.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9727 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2009-01-10 22:18:14 +00:00
parent d32c290846
commit 299e1e814f
4 changed files with 109 additions and 17 deletions

View File

@ -201,6 +201,7 @@ answer newbie questions, and generally made Django that much better:
james_027@yahoo.com
jcrasta@gmail.com
jdetaeye
jhenry <jhenry@theonion.com>
Zak Johnson <zakj@nox.cx>
Nis Jørgensen <nis@superlativ.dk>
Michael Josephson <http://www.sdjournal.com/>

View File

@ -0,0 +1,42 @@
"""
Cached, database-backed sessions.
"""
from django.conf import settings
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.core.cache import cache
class SessionStore(DBStore):
"""
Implements cached, database backed sessions.
"""
def __init__(self, session_key=None):
super(SessionStore, self).__init__(session_key)
def load(self):
data = cache.get(self.session_key, None)
if data is None:
data = super(SessionStore, self).load()
cache.set(self.session_key, data, settings.SESSION_COOKIE_AGE)
return data
def exists(self, session_key):
return super(SessionStore, self).exists(session_key)
def save(self, must_create=False):
super(SessionStore, self).save(must_create)
cache.set(self.session_key, self._session, settings.SESSION_COOKIE_AGE)
def delete(self, session_key=None):
super(SessionStore, self).delete(session_key)
cache.delete(session_key or self.session_key)
def flush(self):
"""
Removes the current session data from the database and regenerates the
key.
"""
self.clear()
self.delete(self.session_key)
self.create()

View File

@ -3,6 +3,7 @@ r"""
>>> from django.conf import settings
>>> from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
>>> from django.contrib.sessions.backends.cache import SessionStore as CacheSession
>>> from django.contrib.sessions.backends.cached_db import SessionStore as CacheDBSession
>>> from django.contrib.sessions.backends.file import SessionStore as FileSession
>>> from django.contrib.sessions.backends.base import SessionBase
>>> from django.contrib.sessions.models import Session
@ -54,6 +55,31 @@ True
>>> db_session.save()
>>> DatabaseSession('1').get('cat')
#
# Cached DB session tests
#
>>> cdb_session = CacheDBSession()
>>> cdb_session.modified
False
>>> cdb_session['cat'] = "dog"
>>> cdb_session.modified
True
>>> cdb_session.pop('cat')
'dog'
>>> cdb_session.pop('some key', 'does not exist')
'does not exist'
>>> cdb_session.save()
>>> cdb_session.exists(cdb_session.session_key)
True
>>> cdb_session.delete(cdb_session.session_key)
>>> cdb_session.exists(cdb_session.session_key)
False
#
# File session tests.
#
# Do file session tests in an isolated directory, and kill it after we're done.
>>> original_session_file_path = settings.SESSION_FILE_PATH
>>> import tempfile

View File

@ -43,6 +43,46 @@ By default, Django stores sessions in your database (using the model
some setups it's faster to store session data elsewhere, so Django can be
configured to store session data on your filesystem or in your cache.
Using cached sessions
---------------------
For better performance, you may want to use a cache-based session backend.
.. versionchanged:: 1.1
Django 1.0 did not include the ``cached_db`` session backend.
To store session data using Django's cache system, you'll first need to make
sure you've configured your cache; see the :ref:`cache documentation
<topics-cache>` for details.
.. warning::
You should only use cache-based sessions if you're using the Memcached cache
backend. The local-memory cache backend doesn't retain data long enough to
be a good choice, and it'll be faster to use file or database sessions
directly instead of sending everything through the file or database cache
backends.
Once your cache in configured, you've got two choices for how to store data in
the cache:
* Set :setting:`SESSION_ENGINE` to
``"django.contrib.sessions.backends.cache"`` for a simple caching session
store. Session data will be stored directly your cache. However, session
data may not be persistant: cached data can be evicted if the cache fills
up or if the cache server is restarted.
* For persistant, cached data, set :setting:`SESSION_ENGINE` to
``"django.contrib.sessions.backends.cached_db"``. This uses a
write-through cache -- every write to the cache will also be written to
the database. Session reads only use the database if the data is not
already in the cache.
Both session stores are quite fast, but the simple cache is faster because it
disreguards persistance. In most cases, the ``cached_db`` backend will be fast
enough, but if you need that last bit of performance, and are willing to let
session data be expunged from time to time, the ``cache`` backend is for you.
Using file-based sessions
-------------------------
@ -54,23 +94,6 @@ to output from ``tempfile.gettempdir()``, most likely ``/tmp``) to control
where Django stores session files. Be sure to check that your Web server has
permissions to read and write to this location.
Using cache-based sessions
--------------------------
To store session data using Django's cache system, set ``SESSION_ENGINE``
to ``"django.contrib.sessions.backends.cache"``. You'll want to make sure
you've configured your cache; see the :ref:`cache documentation <topics-cache>` for details.
.. _cache documentation: ../cache/
.. note::
You should probably only use cache-based sessions if you're using the
Memcached cache backend. The local-memory cache backend doesn't retain data
long enough to be a good choice, and it'll be faster to use file or
database sessions directly instead of sending everything through the file
or database cache backends.
Using sessions in views
=======================