From f1be756730ea02771cb11084b485ac5ad2c38029 Mon Sep 17 00:00:00 2001
From: Martijn Vermaat <martijn@vermaat.name>
Date: Mon, 23 Dec 2013 22:22:42 +0100
Subject: [PATCH] Talking to a Redis server

---
 mutalyzer/config/default_settings.py |  7 +++++-
 mutalyzer/redisclient.py             | 37 ++++++++++++++++++++++++++++
 requirements.txt                     |  2 ++
 3 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 mutalyzer/redisclient.py

diff --git a/mutalyzer/config/default_settings.py b/mutalyzer/config/default_settings.py
index bf622349..e2d93c33 100644
--- a/mutalyzer/config/default_settings.py
+++ b/mutalyzer/config/default_settings.py
@@ -26,7 +26,12 @@ MAX_CACHE_SIZE = 50 * 1048576 # 50 MB
 # Maximum size for uploaded and downloaded files (in bytes).
 MAX_FILE_SIZE = 10 * 1048576 # 10 MB
 
-# Database connection URL (can be any SQLAlchemy connection URI).
+# Redis connection URI (can be any redis-py connection URI). Redis is used
+# for keeping statistics counters. Setting this to `None`, will silently
+# yield a mock Redis.
+REDIS_URI = None
+
+# Database connection URI (can be any SQLAlchemy connection URI).
 DATABASE_URI = 'sqlite://'
 
 # Host name for local MySQL databases.
diff --git a/mutalyzer/redisclient.py b/mutalyzer/redisclient.py
new file mode 100644
index 00000000..45a4fa24
--- /dev/null
+++ b/mutalyzer/redisclient.py
@@ -0,0 +1,37 @@
+"""
+Lazy global interface to Redis.
+
+Redis connections can safely be shared among threads, so we can keep this very
+simple and just use one global connection pool as created by `StrictRedis`.
+
+.. note:: Redis is only used for non-essential features in Mutalyzer and
+    therefore a Redis server is not a hard requirement to run Mutalyzer.
+
+    If the `REDIS_URI` configuration setting is `None`, we silently
+    instantiate a mock interface to Redis.
+"""
+
+
+import redis
+
+from mutalyzer import settings
+from mutalyzer import util
+
+
+class LazyClient(util.LazyObject):
+    """
+    A lazy proxy for a `StrictRedis` object.
+    """
+    def _setup(self):
+        """
+        Instantiate the Redis interface. This called the first time Redis is
+        used.
+        """
+        if settings.REDIS_URI is None:
+            import mockredis
+            self._wrapped = mockredis.MockRedis(strict=True)
+        else:
+            self._wrapped = redis.StrictRedis.from_url(settings.REDIS_URI)
+
+
+client = LazyCLient()
diff --git a/requirements.txt b/requirements.txt
index 5eaabfc0..8e0456de 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -18,3 +18,5 @@ Jinja2==2.7.1
 -e git+https://github.com/mammadori/magic-python.git#egg=Magic_file_extensions
 Flask==0.10.1
 https://bitbucket.org/zzzeek/sqlalchemy/downloads/SQLAlchemy-0.9.0b1.tar.gz
+redis==2.8.0
+mockredispy==2.8.0.2
-- 
GitLab