cache: Instantiate only one BMemcached cache backend.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2022-04-04 18:27:33 -07:00 committed by Alex Vandiver
parent 52b9c59875
commit c9faefd50e
5 changed files with 23 additions and 2 deletions

View File

@ -61,6 +61,7 @@ module = [
"disposable_email_domains.*", "disposable_email_domains.*",
"django.*", "django.*",
"django_auth_ldap.*", "django_auth_ldap.*",
"django_bmemcached.*",
"django_cte.*", "django_cte.*",
"django_otp.*", "django_otp.*",
"django_scim.*", "django_scim.*",

View File

@ -140,6 +140,7 @@ not_yet_fully_covered = [
"zerver/webhooks/zapier/view.py", "zerver/webhooks/zapier/view.py",
# Cannot have coverage, as tests run in a transaction # Cannot have coverage, as tests run in a transaction
"zerver/lib/safe_session_cached_db.py", "zerver/lib/safe_session_cached_db.py",
"zerver/lib/singleton_bmemcached.py",
] ]
enforce_fully_covered = sorted( enforce_fully_covered = sorted(

View File

@ -0,0 +1,19 @@
import pickle
from functools import lru_cache
from typing import Any, Dict
from django_bmemcached.memcached import BMemcached
@lru_cache(None)
def _get_bmemcached(location: str, params: bytes) -> BMemcached:
return BMemcached(location, pickle.loads(params))
def SingletonBMemcached(location: str, params: Dict[str, Any]) -> BMemcached:
# Django instantiates the cache backend per-task to guard against
# thread safety issues, but BMemcached is already thread-safe and
# does its own per-thread pooling, so make sure we instantiate only
# one to avoid extra connections.
return _get_bmemcached(location, pickle.dumps(params))

View File

@ -96,7 +96,7 @@ def clear_database() -> None:
# With `zproject.test_settings`, we aren't using real memcached # With `zproject.test_settings`, we aren't using real memcached
# and; we only need to flush memcached if we're populating a # and; we only need to flush memcached if we're populating a
# database that would be used with it (i.e. zproject.dev_settings). # database that would be used with it (i.e. zproject.dev_settings).
if default_cache["BACKEND"] == "django_bmemcached.memcached.BMemcached": if default_cache["BACKEND"] == "zerver.lib.singleton_bmemcached.SingletonBMemcached":
bmemcached.Client( bmemcached.Client(
(default_cache["LOCATION"],), (default_cache["LOCATION"],),
**default_cache["OPTIONS"], **default_cache["OPTIONS"],

View File

@ -340,7 +340,7 @@ MEMCACHED_PASSWORD = get_secret("memcached_password")
CACHES = { CACHES = {
"default": { "default": {
"BACKEND": "django_bmemcached.memcached.BMemcached", "BACKEND": "zerver.lib.singleton_bmemcached.SingletonBMemcached",
"LOCATION": MEMCACHED_LOCATION, "LOCATION": MEMCACHED_LOCATION,
"OPTIONS": { "OPTIONS": {
"socket_timeout": 3600, "socket_timeout": 3600,