aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Leon Sandøy <[email protected]>2020-05-16 12:40:06 +0200
committerGravatar Leon Sandøy <[email protected]>2020-05-16 12:40:06 +0200
commit7a501fdecaae186590177fd4ebd6cea64119629e (patch)
tree4bc762beab5bea9e8fdbd41b1eb0a61beb526e1f
parentAdding redis-py to the Pipfile (diff)
Boilerplate for the RedisCacheMixin
We're using __init_subclass__ to initialize our RedisDict with the subclass name as a namespace. This will be prefixed to all data that we store, so that there won't be collisions between different subclasses.
-rw-r--r--bot/mixins/__init__.py3
-rw-r--r--bot/mixins/redis.py56
2 files changed, 59 insertions, 0 deletions
diff --git a/bot/mixins/__init__.py b/bot/mixins/__init__.py
new file mode 100644
index 000000000..ff1f0c50d
--- /dev/null
+++ b/bot/mixins/__init__.py
@@ -0,0 +1,3 @@
+from .redis import RedisCacheMixin
+
+__all__ = ['RedisCacheMixin']
diff --git a/bot/mixins/redis.py b/bot/mixins/redis.py
new file mode 100644
index 000000000..f19108576
--- /dev/null
+++ b/bot/mixins/redis.py
@@ -0,0 +1,56 @@
+import redis as redis_py
+
+redis = redis_py.Redis(host="redis")
+
+
+class RedisDict(dict):
+ """
+ A dictionary interface for a Redis database.
+
+ Objects created by this class should mostly behave like a normal dictionary,
+ but will store all the data in our Redis database for persistence between restarts.
+
+ There are, however, a few limitations to what kinds of data types can be
+ stored on Redis, so this is a little bit more limited than a regular dict.
+ """
+
+ def __init__(self, namespace: str = "global"):
+ """Initialize the RedisDict with the right namespace."""
+ # TODO: Make namespace collision impossible!
+ # Append a number or something if it exists already.
+ self.namespace = namespace
+
+ # redis.mset({"firedog": "donkeykong"})
+ #
+ # print(redis.get("firedog").decode("utf-8")
+
+
+class RedisCacheMixin:
+ """
+ A mixin which adds a cls.cache parameter which can be used for persistent caching.
+
+ This adds a dictionary-like object called cache which can be treated like a regular dictionary,
+ but which can only store simple data types like ints, strings, and floats.
+
+ To use it, simply subclass it into your class like this:
+
+ class MyCog(Cog, RedisCacheMixin):
+ def some_command(self):
+ # You can now do this!
+ self.cache['some_data'] = some_data
+
+ All the data stored in this cache will probably be available permanently, even if the bot restarts or
+ is updated. However, Redis is not meant to be used for reliable, permanent storage. It may be cleared
+ from time to time, so please only use it for caching data that you can afford to lose.
+
+ If it's really important that your data should never disappear, please use our postgres database instead.
+ """
+
+ def __init_subclass__(cls, **kwargs):
+ """
+ Initialize the cache when subclass is created.
+
+ When this mixin is subclassed, we create a cache using the subclass name as the namespace.
+ This is to prevent collisions between subclasses.
+ """
+ cls.cache = RedisDict(cls.__name__)