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:
parent
d32c290846
commit
299e1e814f
1
AUTHORS
1
AUTHORS
|
@ -201,6 +201,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
james_027@yahoo.com
|
james_027@yahoo.com
|
||||||
jcrasta@gmail.com
|
jcrasta@gmail.com
|
||||||
jdetaeye
|
jdetaeye
|
||||||
|
jhenry <jhenry@theonion.com>
|
||||||
Zak Johnson <zakj@nox.cx>
|
Zak Johnson <zakj@nox.cx>
|
||||||
Nis Jørgensen <nis@superlativ.dk>
|
Nis Jørgensen <nis@superlativ.dk>
|
||||||
Michael Josephson <http://www.sdjournal.com/>
|
Michael Josephson <http://www.sdjournal.com/>
|
||||||
|
|
|
@ -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()
|
|
@ -3,6 +3,7 @@ r"""
|
||||||
>>> from django.conf import settings
|
>>> from django.conf import settings
|
||||||
>>> from django.contrib.sessions.backends.db import SessionStore as DatabaseSession
|
>>> 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.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.file import SessionStore as FileSession
|
||||||
>>> from django.contrib.sessions.backends.base import SessionBase
|
>>> from django.contrib.sessions.backends.base import SessionBase
|
||||||
>>> from django.contrib.sessions.models import Session
|
>>> from django.contrib.sessions.models import Session
|
||||||
|
@ -54,6 +55,31 @@ True
|
||||||
>>> db_session.save()
|
>>> db_session.save()
|
||||||
>>> DatabaseSession('1').get('cat')
|
>>> 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.
|
# Do file session tests in an isolated directory, and kill it after we're done.
|
||||||
>>> original_session_file_path = settings.SESSION_FILE_PATH
|
>>> original_session_file_path = settings.SESSION_FILE_PATH
|
||||||
>>> import tempfile
|
>>> import tempfile
|
||||||
|
|
|
@ -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
|
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.
|
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
|
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
|
where Django stores session files. Be sure to check that your Web server has
|
||||||
permissions to read and write to this location.
|
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
|
Using sessions in views
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue