Limiting the size of the cache
[theonering] / src / gvoice / conversations.py
index f6fe4b2..5f3d371 100644 (file)
@@ -16,11 +16,14 @@ import util.coroutines as coroutines
 import util.misc as misc_utils
 
 
-_moduleLogger = logging.getLogger("gvoice.conversations")
+_moduleLogger = logging.getLogger(__name__)
 
 
 class Conversations(object):
 
+       OLDEST_COMPATIBLE_FORMAT_VERSION = misc_utils.parse_version("0.8.0")
+       OLDEST_MESSAGE_WINDOW = datetime.timedelta(days=60)
+
        def __init__(self, getter):
                self._get_raw_conversations = getter
                self._conversations = {}
@@ -36,19 +39,26 @@ class Conversations(object):
                try:
                        with open(path, "rb") as f:
                                fileVersion, fileBuild, convs = pickle.load(f)
-               except (pickle.PickleError, IOError):
+               except (pickle.PickleError, IOError, EOFError, ValueError):
                        _moduleLogger.exception("While loading for %s" % self._name)
                        return
 
-               if fileVersion == constants.__version__ and fileBuild == constants.__build__:
+               if misc_utils.compare_versions(
+                       self.OLDEST_COMPATIBLE_FORMAT_VERSION,
+                       misc_utils.parse_version(fileVersion),
+               ) <= 0:
                        self._conversations = convs
                else:
                        _moduleLogger.debug(
-                               "%s Skipping cache due to version mismatch (%s-%s)" % (self._name, fileVersion, fileBuild)
+                               "%s Skipping cache due to version mismatch (%s-%s)" % (
+                                       self._name, fileVersion, fileBuild
+                               )
                        )
 
        def save(self, path):
                try:
+                       for conv in self._conversations.itervalues():
+                               conv.compress(self.OLDEST_MESSAGE_WINDOW)
                        dataToDump = (constants.__version__, constants.__build__, self._conversations)
                        with open(path, "wb") as f:
                                pickle.dump(dataToDump, f, pickle.HIGHEST_PROTOCOL)
@@ -136,6 +146,21 @@ class MergedConversations(object):
        def conversations(self):
                return self._conversations
 
+       def compress(self, timedelta):
+               now = datetime.datetime.now()
+               oldNumConvs = len(self._conversations)
+               oldConvs = self._conversations
+               self._conversations = [
+                       conv
+                       for conv in self._conversations
+                       if (now - conv.time) < timedelta
+               ]
+               newNumConvs = len(self._conversations)
+               if oldNumConvs != newNumConvs:
+                       _moduleLogger.debug("Compressed conversations from %s to %s" % (oldNumConvs, newNumConvs))
+               else:
+                       _moduleLogger.debug("Did not compress, %s" % (newNumConvs))
+
        def _validate(self, newConversation):
                if not self._conversations:
                        return