commit 70fe1215a01020a87c9cdee139f4188b1424d006
Author: Damian Johnson <atagar(a)torproject.org>
Date: Thu Aug 31 10:41:22 2017 -0700
Move cache to its own module
Not yet even close to what I'm planning, but moving this out of the base module
is a good first step.
---
nyx/__init__.py | 53 +-------------------------------------
nyx/cache.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test/cache.py | 26 +++++++++----------
3 files changed, 93 insertions(+), 65 deletions(-)
diff --git a/nyx/__init__.py b/nyx/__init__.py
index 8c3d396..c2032bc 100644
--- a/nyx/__init__.py
+++ b/nyx/__init__.py
@@ -31,10 +31,8 @@ Tor curses monitoring application.
+- halt - stops daemon panels
"""
-import contextlib
import distutils.spawn
import os
-import sqlite3
import sys
import threading
import time
@@ -55,6 +53,7 @@ __license__ = 'GPLv3'
__all__ = [
'arguments',
+ 'cache',
'controller',
'curses',
'log',
@@ -86,17 +85,6 @@ CONFIG = stem.util.conf.config_dict('nyx', {
NYX_INTERFACE = None
TOR_CONTROLLER = None
BASE_DIR = os.path.sep.join(__file__.split(os.path.sep)[:-1])
-CACHE = None
-CACHE_LOCK = threading.RLock()
-
-SCHEMA_VERSION = 1 # version of our scheme, bump this if you change the following
-SCHEMA = (
- 'CREATE TABLE schema(version NUMBER)',
- 'INSERT INTO schema(version) VALUES (%i)' % SCHEMA_VERSION,
-
- 'CREATE TABLE relays(fingerprint TEXT PRIMARY KEY, address TEXT, or_port NUMBER, nickname TEXT)',
-)
-
# technically can change but we use this query a *lot* so needs to be cached
@@ -263,45 +251,6 @@ def data_directory(filename, config):
return os.path.join(data_dir, filename)
-(a)contextlib.contextmanager
-def cache():
- """
- Provides the sqlite cache for application data.
-
- :returns: **sqlite3.Connection** for our applicaion cache
- """
-
- global CACHE
-
- with CACHE_LOCK:
- if CACHE is None:
- cache_path = data_directory('cache.sqlite')
-
- if cache_path:
- try:
- CACHE = sqlite3.connect(cache_path)
- schema = CACHE.execute('SELECT version FROM schema').fetchone()[0]
- except:
- schema = 'no schema'
-
- if schema != SCHEMA_VERSION:
- stem.util.log.info('Cache schema of %s is out of date (has %s but current version is %s). Clearing the cache.' % (cache_path, schema, SCHEMA_VERSION))
-
- CACHE.close()
- os.remove(cache_path)
- CACHE = sqlite3.connect(cache_path)
-
- for cmd in SCHEMA:
- CACHE.execute(cmd)
- else:
- CACHE = sqlite3.connect(':memory:')
-
- for cmd in SCHEMA:
- CACHE.execute(cmd)
-
- yield CACHE
-
-
@uses_settings
def expand_path(path, config):
"""
diff --git a/nyx/cache.py b/nyx/cache.py
new file mode 100644
index 0000000..b989f20
--- /dev/null
+++ b/nyx/cache.py
@@ -0,0 +1,79 @@
+"""
+Cache for frequently needed information. This persists to disk if we can, and
+otherwise is an in-memory cache.
+"""
+
+import contextlib
+import os
+import sqlite3
+import threading
+
+import stem.util.log
+
+import nyx
+
+CACHE = None
+CACHE_LOCK = threading.RLock()
+
+SCHEMA_VERSION = 1 # version of our scheme, bump this if you change the following
+SCHEMA = (
+ 'CREATE TABLE schema(version NUMBER)',
+ 'INSERT INTO schema(version) VALUES (%i)' % SCHEMA_VERSION,
+
+ 'CREATE TABLE relays(fingerprint TEXT PRIMARY KEY, address TEXT, or_port NUMBER, nickname TEXT)',
+)
+
+
+(a)contextlib.contextmanager
+def cache():
+ """
+ Provides the sqlite cache for application data.
+
+ :returns: :class:`~nyx.cache.Cache` for our applicaion
+ """
+
+ global CACHE
+
+ with CACHE_LOCK:
+ if CACHE is None:
+ CACHE = Cache()
+
+ yield CACHE
+
+
+class Cache(object):
+ """
+ Cache for frequently used information.
+ """
+
+ def __init__(self):
+ cache_path = nyx.data_directory('cache.sqlite')
+
+ if cache_path:
+ try:
+ self._conn = sqlite3.connect(cache_path)
+ schema = self._conn.execute('SELECT version FROM schema').fetchone()[0]
+ except:
+ schema = 'no schema'
+
+ if schema != SCHEMA_VERSION:
+ stem.util.log.info('Cache schema of %s is out of date (has %s but current version is %s). Clearing the cache.' % (cache_path, schema, SCHEMA_VERSION))
+
+ self._conn.close()
+ os.remove(cache_path)
+ self._conn = sqlite3.connect(cache_path)
+
+ for cmd in SCHEMA:
+ self._conn.execute(cmd)
+ else:
+ self._conn = sqlite3.connect(':memory:')
+
+ for cmd in SCHEMA:
+ self._conn.execute(cmd)
+
+ def query(self, query, *param):
+ """
+ Performs a query on our cache.
+ """
+
+ return self._conn.execute(query, param)
diff --git a/test/cache.py b/test/cache.py
index 01f99af..733fbca 100644
--- a/test/cache.py
+++ b/test/cache.py
@@ -5,7 +5,7 @@ Unit tests for nyx.cache.
import tempfile
import unittest
-import nyx
+import nyx.cache
from mock import Mock, patch
@@ -17,7 +17,7 @@ NICKNAME = 'caersidi'
class TestCache(unittest.TestCase):
def setUp(self):
- nyx.CACHE = None # drop cached database reference
+ nyx.cache.CACHE = None # drop cached database reference
@patch('nyx.data_directory', Mock(return_value = None))
def test_memory_cache(self):
@@ -25,10 +25,10 @@ class TestCache(unittest.TestCase):
Create a cache in memory.
"""
- with nyx.cache() as cache:
- self.assertEqual((0, 'main', ''), cache.execute("PRAGMA database_list").fetchone())
- cache.execute('INSERT INTO relays(fingerprint, address, or_port, nickname) VALUES (?,?,?,?)', (FINGERPRINT, ADDRESS, PORT, NICKNAME))
- self.assertEqual(NICKNAME, cache.execute('SELECT nickname FROM relays WHERE fingerprint=?', (FINGERPRINT,)).fetchone()[0])
+ with nyx.cache.cache() as cache:
+ self.assertEqual((0, 'main', ''), cache.query('PRAGMA database_list').fetchone())
+ cache.query('INSERT INTO relays(fingerprint, address, or_port, nickname) VALUES (?,?,?,?)', FINGERPRINT, ADDRESS, PORT, NICKNAME)
+ self.assertEqual(NICKNAME, cache.query('SELECT nickname FROM relays WHERE fingerprint=?', FINGERPRINT).fetchone()[0])
def test_file_cache(self):
"""
@@ -37,12 +37,12 @@ class TestCache(unittest.TestCase):
with tempfile.NamedTemporaryFile(suffix = '.sqlite') as tmp:
with patch('nyx.data_directory', Mock(return_value = tmp.name)):
- with nyx.cache() as cache:
- self.assertEqual((0, 'main', tmp.name), cache.execute("PRAGMA database_list").fetchone())
- cache.execute('INSERT INTO relays(fingerprint, address, or_port, nickname) VALUES (?,?,?,?)', (FINGERPRINT, ADDRESS, PORT, NICKNAME))
- cache.commit()
+ with nyx.cache.cache() as cache:
+ self.assertEqual((0, 'main', tmp.name), cache.query('PRAGMA database_list').fetchone())
+ cache.query('INSERT INTO relays(fingerprint, address, or_port, nickname) VALUES (?,?,?,?)', FINGERPRINT, ADDRESS, PORT, NICKNAME)
+ cache._conn.commit()
- nyx.CACHE = None
+ nyx.cache.CACHE = None
- with nyx.cache() as cache:
- self.assertEqual(NICKNAME, cache.execute('SELECT nickname FROM relays WHERE fingerprint=?', (FINGERPRINT,)).fetchone()[0])
+ with nyx.cache.cache() as cache:
+ self.assertEqual(NICKNAME, cache.query('SELECT nickname FROM relays WHERE fingerprint=?', FINGERPRINT).fetchone()[0])