changeset 2147:d25bd432bc3e beta

- #347 when running multiple RhodeCode instances, properly invalidates cache for all registered servers - server start also clears all cache keys now
author Marcin Kuzminski <marcin@python-works.com>
date Tue, 20 Mar 2012 23:28:41 +0200
parents ee45677c4edc
children ad127a5cef73
files docs/changelog.rst rhodecode/lib/utils.py rhodecode/model/db.py rhodecode/model/scm.py
diffstat 4 files changed, 47 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/docs/changelog.rst	Tue Mar 20 23:26:02 2012 +0200
+++ b/docs/changelog.rst	Tue Mar 20 23:28:41 2012 +0200
@@ -28,6 +28,8 @@
 - #402 removed group prefix from repository name when listing repositories 
   inside a group
 - added gravatars into permission view and permissions autocomplete
+- #347 when running multiple RhodeCode instances, properly invalidates cache 
+  for all registered servers
 
 fixes
 +++++
--- a/rhodecode/lib/utils.py	Tue Mar 20 23:26:02 2012 +0200
+++ b/rhodecode/lib/utils.py	Tue Mar 20 23:28:41 2012 +0200
@@ -51,7 +51,8 @@
 
 from rhodecode.model import meta
 from rhodecode.model.db import Repository, User, RhodeCodeUi, \
-    UserLog, RepoGroup, RhodeCodeSetting, UserRepoGroupToPerm
+    UserLog, RepoGroup, RhodeCodeSetting, UserRepoGroupToPerm,\
+    CacheInvalidation
 from rhodecode.model.meta import Session
 from rhodecode.model.repos_group import ReposGroupModel
 from rhodecode.lib.utils2 import safe_str, safe_unicode
@@ -452,13 +453,19 @@
     sa.commit()
     removed = []
     if remove_obsolete:
-        #remove from database those repositories that are not in the filesystem
+        # remove from database those repositories that are not in the filesystem
         for repo in sa.query(Repository).all():
             if repo.repo_name not in initial_repo_list.keys():
+                log.debug("Removing non existing repository found in db %s" %
+                          repo.repo_name)
                 removed.append(repo.repo_name)
                 sa.delete(repo)
                 sa.commit()
 
+    # clear cache keys
+    log.debug("Clearing cache keys now...")
+    CacheInvalidation.clear_cache()
+    sa.commit()
     return added, removed
 
 
--- a/rhodecode/model/db.py	Tue Mar 20 23:26:02 2012 +0200
+++ b/rhodecode/model/db.py	Tue Mar 20 23:28:41 2012 +0200
@@ -1042,11 +1042,14 @@
     def __repr__(self):
         return "<%s('%s:%s')>" % (self.__class__.__name__,
                                   self.cache_id, self.cache_key)
+    @classmethod
+    def clear_cache(cls):
+        cls.query().delete()
 
     @classmethod
     def _get_key(cls, key):
         """
-        Wrapper for generating a key
+        Wrapper for generating a key, together with a prefix
 
         :param key:
         """
@@ -1055,12 +1058,25 @@
         iid = rhodecode.CONFIG.get('instance_id')
         if iid:
             prefix = iid
-        return "%s%s" % (prefix, key)
+        return "%s%s" % (prefix, key), prefix, key.rstrip('_README')
 
     @classmethod
     def get_by_key(cls, key):
         return cls.query().filter(cls.cache_key == key).scalar()
-
+    
+    @classmethod
+    def _get_or_create_key(cls, key, prefix, org_key):
+        inv_obj = Session.query(cls).filter(cls.cache_key == key).scalar()
+        if not inv_obj:
+            try:
+                inv_obj = CacheInvalidation(key, org_key)
+                Session.add(inv_obj)
+                Session.commit()
+            except Exception:
+                log.error(traceback.format_exc())
+                Session.rollback()                
+        return inv_obj
+            
     @classmethod
     def invalidate(cls, key):
         """
@@ -1070,10 +1086,12 @@
 
         :param key:
         """
-        return cls.query()\
-                .filter(CacheInvalidation.cache_key == key)\
-                .filter(CacheInvalidation.cache_active == False)\
-                .scalar()
+        
+        key, _prefix, _org_key = cls._get_key(key)
+        inv = cls._get_or_create_key(key, _prefix, _org_key)
+
+        if inv and inv.cache_active is False:
+            return inv
 
     @classmethod
     def set_invalidate(cls, key):
@@ -1083,17 +1101,16 @@
         :param key:
         """
 
-        log.debug('marking %s for invalidation' % key)
-        inv_obj = Session.query(cls)\
-            .filter(cls.cache_key == key).scalar()
-        if inv_obj:
-            inv_obj.cache_active = False
-        else:
-            log.debug('cache key not found in invalidation db -> creating one')
-            inv_obj = CacheInvalidation(key)
+        key, _prefix, _org_key = cls._get_key(key)
+        inv_objs = Session.query(cls).filter(cls.cache_args == _org_key).all()
+        log.debug('marking %s key[s] %s for invalidation' % (len(inv_objs),
+                                                             _org_key))
+        try:
+            for inv_obj in inv_objs:
+                if inv_obj:
+                    inv_obj.cache_active = False
 
-        try:
-            Session.add(inv_obj)
+                Session.add(inv_obj)
             Session.commit()
         except Exception:
             log.error(traceback.format_exc())
--- a/rhodecode/model/scm.py	Tue Mar 20 23:26:02 2012 +0200
+++ b/rhodecode/model/scm.py	Tue Mar 20 23:28:41 2012 +0200
@@ -235,13 +235,13 @@
         return group_iter
 
     def mark_for_invalidation(self, repo_name):
-        """Puts cache invalidation task into db for
+        """
+        Puts cache invalidation task into db for
         further global cache invalidation
 
         :param repo_name: this repo that should invalidation take place
         """
         CacheInvalidation.set_invalidate(repo_name)
-        CacheInvalidation.set_invalidate(repo_name + "_README")
 
     def toggle_following_repo(self, follow_repo_id, user_id):