Mercurial > kallithea
diff rhodecode/model/scm.py @ 692:cb0d9ce6ac5c beta
#50 on point cache invalidation changes.
Created cacheInvalidation table
cleaned up sa sessions from models, since it wasn't really needed.
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 15 Nov 2010 02:26:19 +0100 |
parents | 7486da5f0628 |
children | 90ac3255c117 |
line wrap: on
line diff
--- a/rhodecode/model/scm.py Sun Nov 14 22:54:16 2010 +0100 +++ b/rhodecode/model/scm.py Mon Nov 15 02:26:19 2010 +0100 @@ -28,12 +28,15 @@ from rhodecode.lib.auth import HasRepoPermissionAny from rhodecode.lib.utils import get_repos from rhodecode.model import meta -from rhodecode.model.db import Repository, User, RhodeCodeUi +from rhodecode.model.db import Repository, User, RhodeCodeUi, CacheInvalidation +from rhodecode.model.caching_query import FromCache from sqlalchemy.orm import joinedload +from sqlalchemy.orm.session import make_transient from vcs import get_backend from vcs.utils.helpers import get_scm from vcs.exceptions import RepositoryError, VCSError from vcs.utils.lazy import LazyProperty +import traceback import logging import os import time @@ -45,12 +48,8 @@ Mercurial Model """ - def __init__(self, sa=None): - if not sa: - self.sa = meta.Session() - else: - self.sa = sa - + def __init__(self): + self.sa = meta.Session() @LazyProperty def repos_path(self): @@ -143,7 +142,7 @@ 'repository.admin')(repo_name, 'get repo check'): return - @cache_region('long_term', 'get_repo_cached_%s' % repo_name) + @cache_region('long_term') def _get_repo(repo_name): repo_path = os.path.join(self.repos_path, repo_name) @@ -165,13 +164,76 @@ .options(joinedload(Repository.user))\ .filter(Repository.repo_name == repo_name)\ .scalar() + make_transient(dbrepo) repo.dbrepo = dbrepo return repo - invalidate = False + invalidate = self._should_invalidate(repo_name) if invalidate: - log.info('INVALIDATING CACHE FOR %s', repo_name) + log.info('invalidating cache for repository %s', repo_name) region_invalidate(_get_repo, None, repo_name) + self._mark_invalidated(invalidate) return _get_repo(repo_name) + + + def mark_for_invalidation(self, repo_name): + """ + Puts cache invalidation task into db for + further global cache invalidation + + :param repo_name: this repo that should invalidation take place + """ + log.debug('marking %s for invalidation', repo_name) + cache = self.sa.query(CacheInvalidation)\ + .filter(CacheInvalidation.cache_key == repo_name).scalar() + + if cache: + #mark this cache as inactive + cache.cache_active = False + else: + log.debug('cache key not found in invalidation db -> creating one') + cache = CacheInvalidation(repo_name) + + try: + self.sa.add(cache) + self.sa.commit() + except: + log.error(traceback.format_exc()) + self.sa.rollback() + + + + + + def _should_invalidate(self, repo_name): + """ + Looks up database for invalidation signals for this repo_name + :param repo_name: + """ + + ret = self.sa.query(CacheInvalidation)\ + .options(FromCache('sql_cache_short', + 'get_invalidation_%s' % repo_name))\ + .filter(CacheInvalidation.cache_key == repo_name)\ + .filter(CacheInvalidation.cache_active == False)\ + .scalar() + + return ret + + def _mark_invalidated(self, cache_key): + """ + Marks all occurences of cache to invaldation as already invalidated + @param repo_name: + """ + if cache_key: + log.debug('marking %s as already invalidated', cache_key) + try: + cache_key.cache_active = True + self.sa.add(cache_key) + self.sa.commit() + except: + log.error(traceback.format_exc()) + self.sa.rollback() +