mirror of https://github.com/zulip/zulip.git
session: Enforce that changes cannot happen in a transaction.
This commit is contained in:
parent
b70a071124
commit
7650b5a972
|
@ -140,6 +140,8 @@ not_yet_fully_covered = [
|
|||
"zerver/webhooks/teamcity/view.py",
|
||||
"zerver/webhooks/travis/view.py",
|
||||
"zerver/webhooks/zapier/view.py",
|
||||
# Cannot have coverage, as tests run in a transaction
|
||||
"zerver/lib/safe_session_cached_db.py",
|
||||
]
|
||||
|
||||
enforce_fully_covered = sorted(
|
||||
|
|
|
@ -56,7 +56,7 @@ def huddle_cache_items(items_for_remote_cache: Dict[str, Tuple[Huddle]], huddle:
|
|||
|
||||
|
||||
def session_cache_items(items_for_remote_cache: Dict[str, str], session: Session) -> None:
|
||||
if settings.SESSION_ENGINE != "django.contrib.sessions.backends.cached_db":
|
||||
if settings.SESSION_ENGINE != "zerver.lib.safe_session_cached_db":
|
||||
# If we're not using the cached_db session engine, we there
|
||||
# will be no store.cache_key attribute, and in any case we
|
||||
# don't need to fill the cache, since it won't exist.
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
from typing import Optional
|
||||
|
||||
from django.contrib.sessions.backends.cached_db import SessionStore as CachedDbSessionStore
|
||||
from django.db.transaction import get_connection
|
||||
|
||||
|
||||
class SessionStore(CachedDbSessionStore):
|
||||
"""Caching session object which does not leak into the cache.
|
||||
|
||||
django.contrib.sessions.backends.cached_db does write-through to
|
||||
the cache and the backing database. If the database is in a
|
||||
transaction, this may leak not-yet-committed changes to the cache,
|
||||
which can lead to inconsistent state. This class wraps changes to
|
||||
the session in assertions which enforce that the database cannot
|
||||
be in a transaction before writing.
|
||||
|
||||
"""
|
||||
|
||||
def save(self, must_create: bool = False) -> None:
|
||||
assert not get_connection().in_atomic_block
|
||||
super().save(must_create)
|
||||
|
||||
def delete(self, session_key: Optional[str] = None) -> None:
|
||||
assert not get_connection().in_atomic_block
|
||||
super().delete(session_key)
|
|
@ -334,7 +334,7 @@ RABBITMQ_PASSWORD = get_secret("rabbitmq_password")
|
|||
# CACHING CONFIGURATION
|
||||
########################################################################
|
||||
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||
SESSION_ENGINE = "zerver.lib.safe_session_cached_db"
|
||||
|
||||
MEMCACHED_PASSWORD = get_secret("memcached_password")
|
||||
|
||||
|
|
Loading…
Reference in New Issue