We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
memcached cache backend does not really test memcached
@autrilla reported that when he moved Kinto to GCP, the heartbeat reported success for all backends, including cache, even though there is no `memcached`. I think the problem is here:

https://github.com/Kinto/kinto/blob/61494caae2bb8fe342f32f6a5d89f40ed2b62dff/kinto/core/cache/__init__.py#L87-L91

The heartbeat for the cache backend just sends two messages which don't expect responses. For something like memcached which communicates over UDP, these messages can "succeed" by silently going nowhere.
memcached cache backend does not really test memcached
@autrilla reported that when he moved Kinto to GCP, the heartbeat reported success for all backends, including cache, even though there is no `memcached`. I think the problem is here:

https://github.com/Kinto/kinto/blob/61494caae2bb8fe342f32f6a5d89f40ed2b62dff/kinto/core/cache/__init__.py#L87-L91

The heartbeat for the cache backend just sends two messages which don't expect responses. For something like memcached which communicates over UDP, these messages can "succeed" by silently going nowhere.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kinto/core/cache/__init__.py`
Content:
```
1 import logging
2 import random
3 
4 
5 logger = logging.getLogger(__name__)
6 
7 
8 _HEARTBEAT_DELETE_RATE = 0.5
9 _HEARTBEAT_KEY = "__heartbeat__"
10 _HEARTBEAT_TTL_SECONDS = 3600
11 
12 
13 class CacheBase:
14     def __init__(self, *args, **kwargs):
15         self.prefix = kwargs["cache_prefix"]
16         self.max_size_bytes = kwargs.get("cache_max_size_bytes")
17 
18     def initialize_schema(self, dry_run=False):
19         """Create every necessary objects (like tables or indices) in the
20         backend.
21 
22         This is executed when the ``kinto migrate`` command is run.
23 
24         :param bool dry_run: simulate instead of executing the operations.
25         """
26         raise NotImplementedError
27 
28     def flush(self):
29         """Delete every values."""
30         raise NotImplementedError
31 
32     def ttl(self, key):
33         """Obtain the expiration value of the specified `key`.
34 
35         :param str key: key
36         :returns: number of seconds or negative if no TTL.
37         :rtype: float
38         """
39         raise NotImplementedError
40 
41     def expire(self, key, ttl):
42         """Set the expiration value `ttl` for the specified `key`.
43 
44         :param str key: key
45         :param float ttl: number of seconds
46         """
47         raise NotImplementedError
48 
49     def set(self, key, value, ttl):
50         """Store a value with the specified `key`.
51 
52         :param str key: key
53         :param str value: value to store
54         :param float ttl: expire after number of seconds
55         """
56         raise NotImplementedError
57 
58     def get(self, key):
59         """Obtain the value of the specified `key`.
60 
61         :param str key: key
62         :returns: the stored value or None if missing.
63         :rtype: str
64         """
65         raise NotImplementedError
66 
67     def delete(self, key):
68         """Delete the value of the specified `key`.
69 
70         :param str key: key
71         """
72         raise NotImplementedError
73 
74 
75 def heartbeat(backend):
76     def ping(request):
77         """Test that cache backend is operational.
78 
79         :param request: current request object
80         :type request: :class:`~pyramid:pyramid.request.Request`
81         :returns: ``True`` is everything is ok, ``False`` otherwise.
82         :rtype: bool
83         """
84         # No specific case for readonly mode because the cache should
85         # continue to work in that mode.
86         try:
87             if random.SystemRandom().random() < _HEARTBEAT_DELETE_RATE:
88                 backend.delete(_HEARTBEAT_KEY)
89             else:
90                 backend.set(_HEARTBEAT_KEY, "alive", _HEARTBEAT_TTL_SECONDS)
91             return True
92         except Exception:
93             logger.exception("Heartbeat Failure")
94             return False
95 
96     return ping
97
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kinto/core/cache/__init__.py b/kinto/core/cache/__init__.py
--- a/kinto/core/cache/__init__.py
+++ b/kinto/core/cache/__init__.py
@@ -86,9 +86,9 @@
         try:
             if random.SystemRandom().random() < _HEARTBEAT_DELETE_RATE:
                 backend.delete(_HEARTBEAT_KEY)
-            else:
-                backend.set(_HEARTBEAT_KEY, "alive", _HEARTBEAT_TTL_SECONDS)
-            return True
+                return backend.get(_HEARTBEAT_KEY) is None
+            backend.set(_HEARTBEAT_KEY, "alive", _HEARTBEAT_TTL_SECONDS)
+            return backend.get(_HEARTBEAT_KEY) == "alive"
         except Exception:
             logger.exception("Heartbeat Failure")
             return False

{"golden_diff": "diff --git a/kinto/core/cache/__init__.py b/kinto/core/cache/__init__.py\n--- a/kinto/core/cache/__init__.py\n+++ b/kinto/core/cache/__init__.py\n@@ -86,9 +86,9 @@\n         try:\n             if random.SystemRandom().random() < _HEARTBEAT_DELETE_RATE:\n                 backend.delete(_HEARTBEAT_KEY)\n-            else:\n-                backend.set(_HEARTBEAT_KEY, \"alive\", _HEARTBEAT_TTL_SECONDS)\n-            return True\n+                return backend.get(_HEARTBEAT_KEY) is None\n+            backend.set(_HEARTBEAT_KEY, \"alive\", _HEARTBEAT_TTL_SECONDS)\n+            return backend.get(_HEARTBEAT_KEY) == \"alive\"\n         except Exception:\n             logger.exception(\"Heartbeat Failure\")\n             return False\n", "issue": "memcached cache backend does not really test memcached\n@autrilla reported that when he moved Kinto to GCP, the heartbeat reported success for all backends, including cache, even though there is no `memcached`. I think the problem is here:\r\n\r\nhttps://github.com/Kinto/kinto/blob/61494caae2bb8fe342f32f6a5d89f40ed2b62dff/kinto/core/cache/__init__.py#L87-L91\r\n\r\nThe heartbeat for the cache backend just sends two messages which don't expect responses. For something like memcached which communicates over UDP, these messages can \"succeed\" by silently going nowhere.\nmemcached cache backend does not really test memcached\n@autrilla reported that when he moved Kinto to GCP, the heartbeat reported success for all backends, including cache, even though there is no `memcached`. I think the problem is here:\r\n\r\nhttps://github.com/Kinto/kinto/blob/61494caae2bb8fe342f32f6a5d89f40ed2b62dff/kinto/core/cache/__init__.py#L87-L91\r\n\r\nThe heartbeat for the cache backend just sends two messages which don't expect responses. For something like memcached which communicates over UDP, these messages can \"succeed\" by silently going nowhere.\n", "before_files": [{"content": "import logging\nimport random\n\n\nlogger = logging.getLogger(__name__)\n\n\n_HEARTBEAT_DELETE_RATE = 0.5\n_HEARTBEAT_KEY = \"__heartbeat__\"\n_HEARTBEAT_TTL_SECONDS = 3600\n\n\nclass CacheBase:\n    def __init__(self, *args, **kwargs):\n        self.prefix = kwargs[\"cache_prefix\"]\n        self.max_size_bytes = kwargs.get(\"cache_max_size_bytes\")\n\n    def initialize_schema(self, dry_run=False):\n        \"\"\"Create every necessary objects (like tables or indices) in the\n        backend.\n\n        This is executed when the ``kinto migrate`` command is run.\n\n        :param bool dry_run: simulate instead of executing the operations.\n        \"\"\"\n        raise NotImplementedError\n\n    def flush(self):\n        \"\"\"Delete every values.\"\"\"\n        raise NotImplementedError\n\n    def ttl(self, key):\n        \"\"\"Obtain the expiration value of the specified `key`.\n\n        :param str key: key\n        :returns: number of seconds or negative if no TTL.\n        :rtype: float\n        \"\"\"\n        raise NotImplementedError\n\n    def expire(self, key, ttl):\n        \"\"\"Set the expiration value `ttl` for the specified `key`.\n\n        :param str key: key\n        :param float ttl: number of seconds\n        \"\"\"\n        raise NotImplementedError\n\n    def set(self, key, value, ttl):\n        \"\"\"Store a value with the specified `key`.\n\n        :param str key: key\n        :param str value: value to store\n        :param float ttl: expire after number of seconds\n        \"\"\"\n        raise NotImplementedError\n\n    def get(self, key):\n        \"\"\"Obtain the value of the specified `key`.\n\n        :param str key: key\n        :returns: the stored value or None if missing.\n        :rtype: str\n        \"\"\"\n        raise NotImplementedError\n\n    def delete(self, key):\n        \"\"\"Delete the value of the specified `key`.\n\n        :param str key: key\n        \"\"\"\n        raise NotImplementedError\n\n\ndef heartbeat(backend):\n    def ping(request):\n        \"\"\"Test that cache backend is operational.\n\n        :param request: current request object\n        :type request: :class:`~pyramid:pyramid.request.Request`\n        :returns: ``True`` is everything is ok, ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        # No specific case for readonly mode because the cache should\n        # continue to work in that mode.\n        try:\n            if random.SystemRandom().random() < _HEARTBEAT_DELETE_RATE:\n                backend.delete(_HEARTBEAT_KEY)\n            else:\n                backend.set(_HEARTBEAT_KEY, \"alive\", _HEARTBEAT_TTL_SECONDS)\n            return True\n        except Exception:\n            logger.exception(\"Heartbeat Failure\")\n            return False\n\n    return ping\n", "path": "kinto/core/cache/__init__.py"}], "after_files": [{"content": "import logging\nimport random\n\n\nlogger = logging.getLogger(__name__)\n\n\n_HEARTBEAT_DELETE_RATE = 0.5\n_HEARTBEAT_KEY = \"__heartbeat__\"\n_HEARTBEAT_TTL_SECONDS = 3600\n\n\nclass CacheBase:\n    def __init__(self, *args, **kwargs):\n        self.prefix = kwargs[\"cache_prefix\"]\n        self.max_size_bytes = kwargs.get(\"cache_max_size_bytes\")\n\n    def initialize_schema(self, dry_run=False):\n        \"\"\"Create every necessary objects (like tables or indices) in the\n        backend.\n\n        This is executed when the ``kinto migrate`` command is run.\n\n        :param bool dry_run: simulate instead of executing the operations.\n        \"\"\"\n        raise NotImplementedError\n\n    def flush(self):\n        \"\"\"Delete every values.\"\"\"\n        raise NotImplementedError\n\n    def ttl(self, key):\n        \"\"\"Obtain the expiration value of the specified `key`.\n\n        :param str key: key\n        :returns: number of seconds or negative if no TTL.\n        :rtype: float\n        \"\"\"\n        raise NotImplementedError\n\n    def expire(self, key, ttl):\n        \"\"\"Set the expiration value `ttl` for the specified `key`.\n\n        :param str key: key\n        :param float ttl: number of seconds\n        \"\"\"\n        raise NotImplementedError\n\n    def set(self, key, value, ttl):\n        \"\"\"Store a value with the specified `key`.\n\n        :param str key: key\n        :param str value: value to store\n        :param float ttl: expire after number of seconds\n        \"\"\"\n        raise NotImplementedError\n\n    def get(self, key):\n        \"\"\"Obtain the value of the specified `key`.\n\n        :param str key: key\n        :returns: the stored value or None if missing.\n        :rtype: str\n        \"\"\"\n        raise NotImplementedError\n\n    def delete(self, key):\n        \"\"\"Delete the value of the specified `key`.\n\n        :param str key: key\n        \"\"\"\n        raise NotImplementedError\n\n\ndef heartbeat(backend):\n    def ping(request):\n        \"\"\"Test that cache backend is operational.\n\n        :param request: current request object\n        :type request: :class:`~pyramid:pyramid.request.Request`\n        :returns: ``True`` is everything is ok, ``False`` otherwise.\n        :rtype: bool\n        \"\"\"\n        # No specific case for readonly mode because the cache should\n        # continue to work in that mode.\n        try:\n            if random.SystemRandom().random() < _HEARTBEAT_DELETE_RATE:\n                backend.delete(_HEARTBEAT_KEY)\n                return backend.get(_HEARTBEAT_KEY) is None\n            backend.set(_HEARTBEAT_KEY, \"alive\", _HEARTBEAT_TTL_SECONDS)\n            return backend.get(_HEARTBEAT_KEY) == \"alive\"\n        except Exception:\n            logger.exception(\"Heartbeat Failure\")\n            return False\n\n    return ping\n", "path": "kinto/core/cache/__init__.py"}]}