Browse Source

ref: vendor django's removed memcached backend (#62682)

to unblock the 4.2 upgrade this is the fastest path -- I will follow up
with pymemcache

<!-- Describe your PR here. -->
anthony sottile 1 year ago
parent
commit
8f77c6e50a
2 changed files with 68 additions and 0 deletions
  1. 0 0
      fixtures/stubs-for-mypy/memcache.pyi
  2. 68 0
      src/sentry/utils/memcached.py

+ 0 - 0
fixtures/stubs-for-mypy/memcache.pyi


+ 68 - 0
src/sentry/utils/memcached.py

@@ -0,0 +1,68 @@
+"""copied from django 4.0 before removal
+
+modified to fix bug with monkeypatching and remove warnings
+
+---
+
+Copyright (c) Django Software Foundation and individual contributors.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of Django nor the names of its contributors may be used
+       to endorse or promote products derived from this software without
+       specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""
+import pickle
+
+from django.core.cache.backends.memcached import BaseMemcachedCache
+
+
+class MemcachedCache(BaseMemcachedCache):
+    "An implementation of a cache binding using python-memcached"
+
+    # python-memcached doesn't support default values in get().
+    # https://github.com/linsomniac/python-memcached/issues/159
+    _missing_key = None
+
+    def __init__(self, server, params):
+        # python-memcached ≥ 1.45 returns None for a nonexistent key in
+        # incr/decr(), python-memcached < 1.45 raises ValueError.
+        import memcache
+
+        super().__init__(server, params, library=memcache, value_not_found_exception=ValueError)
+        self._options = {"pickleProtocol": pickle.HIGHEST_PROTOCOL, **self._options}  # type: ignore[has-type]
+
+    def get(self, key, default=None, version=None):
+        key = self.make_and_validate_key(key, version=version)
+        val = self._cache.get(key)  # type: ignore[attr-defined]
+        # python-memcached doesn't support default values in get().
+        # https://github.com/linsomniac/python-memcached/issues/159
+        # Remove this method if that issue is fixed.
+        if val is None:
+            return default
+        return val
+
+    def delete(self, key, version=None):
+        key = self.make_key(key, version=version)
+        self.validate_key(key)
+        return bool(self._cache.delete(key))  # type: ignore[attr-defined]