@@ -25,12 +25,14 @@ news
inside a repository group
- added alternative HTTP 403 response when client failed to authenticate. Helps
solving issues with Mercurial and LDAP
- #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
+++++
- fixed #390 cache invalidation problems on repos inside group
- fixed #385 clone by ID url was loosing proxy prefix in URL
@@ -48,13 +48,14 @@ from rhodecode.lib.vcs.utils.helpers imp
from rhodecode.lib.vcs.exceptions import VCSError
from rhodecode.lib.caching_query import FromCache
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
from rhodecode.lib.vcs.utils.fakemod import create_module
log = logging.getLogger(__name__)
@@ -449,19 +450,25 @@ def repo2db_mapper(initial_repo_list, re
'group_id': getattr(group, 'group_id', None)
}
rm.create(form_data, user, just_db=True)
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)
# clear cache keys
log.debug("Clearing cache keys now...")
CacheInvalidation.clear_cache()
return added, removed
# set cache regions for beaker so celery can utilise it
def add_cache(settings):
cache_settings = {'regions': None}
@@ -1039,64 +1039,81 @@ class CacheInvalidation(Base, BaseModel)
self.cache_args = cache_args
self.cache_active = False
def __repr__(self):
return "<%s('%s:%s')>" % (self.__class__.__name__,
self.cache_id, self.cache_key)
@classmethod
def clear_cache(cls):
cls.query().delete()
def _get_key(cls, key):
"""
Wrapper for generating a key
Wrapper for generating a key, together with a prefix
:param key:
import rhodecode
prefix = ''
iid = rhodecode.CONFIG.get('instance_id')
if iid:
prefix = iid
return "%s%s" % (prefix, key)
return "%s%s" % (prefix, key), prefix, key.rstrip('_README')
def get_by_key(cls, key):
return cls.query().filter(cls.cache_key == key).scalar()
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
def invalidate(cls, key):
Returns Invalidation object if this given key should be invalidated
None otherwise. `cache_active = False` means that this cache
state is not valid and needs to be invalidated
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
def set_invalidate(cls, key):
Mark this Cache key for invalidation
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)
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))
for inv_obj in inv_objs:
@@ -232,19 +232,19 @@ class ScmModel(BaseModel):
.filter(RepoGroup.group_parent_id == None).all()
group_iter = GroupList(all_groups)
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):
f = self.sa.query(UserFollowing)\
.filter(UserFollowing.follows_repo_id == follow_repo_id)\
.filter(UserFollowing.user_id == user_id).scalar()
Status change: