@@ -2097,97 +2097,103 @@ class CacheInvalidation(Base, BaseModel)
"""
Wrapper for generating a unique cache key for this instance and "key".
key must / will start with a repo_name which will be stored in .cache_args .
import kallithea
prefix = kallithea.CONFIG.get('instance_id', '')
return "%s%s" % (prefix, key)
@classmethod
def set_invalidate(cls, repo_name, delete=False):
Mark all caches of a repo as invalid in the database.
inv_objs = Session().query(cls).filter(cls.cache_args == repo_name).all()
log.debug('for repo %s got %s invalidation objects',
safe_str(repo_name), inv_objs)
for inv_obj in inv_objs:
log.debug('marking %s key for invalidation based on repo_name=%s',
inv_obj, safe_str(repo_name))
if delete:
Session().delete(inv_obj)
else:
inv_obj.cache_active = False
Session().add(inv_obj)
Session().commit()
def test_and_set_valid(cls, repo_name, kind, valid_cache_keys=None):
Mark this cache key as active and currently cached.
Return True if the existing cache registration still was valid.
Return False to indicate that it had been invalidated and caches should be refreshed.
key = (repo_name + '_' + kind) if kind else repo_name
cache_key = cls._get_cache_key(key)
if valid_cache_keys and cache_key in valid_cache_keys:
return True
inv_obj = cls.query().filter(cls.cache_key == cache_key).scalar()
if not inv_obj:
inv_obj = CacheInvalidation(cache_key, repo_name)
if inv_obj.cache_active:
inv_obj.cache_active = True
try:
except exc.IntegrityError:
raise
# TOCTOU - another thread added the key at the same time; no further action required
return False
def get_valid_cache_keys(cls):
Return opaque object with information of which caches still are valid
and can be used without checking for invalidation.
return set(inv_obj.cache_key for inv_obj in cls.query().filter(cls.cache_active).all())
class ChangesetComment(Base, BaseModel):
__tablename__ = 'changeset_comments'
__table_args__ = (
Index('cc_revision_idx', 'revision'),
Index('cc_pull_request_id_idx', 'pull_request_id'),
{'extend_existing': True, 'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
)
comment_id = Column(Integer(), nullable=False, unique=True, primary_key=True)
repo_id = Column(Integer(), ForeignKey('repositories.repo_id'), nullable=False)
revision = Column(String(40))
pull_request_id = Column(Integer(), ForeignKey('pull_requests.pull_request_id'))
line_no = Column(Unicode(10))
f_path = Column(Unicode(1000))
user_id = Column(Integer(), ForeignKey('users.user_id'), nullable=False)
text = Column(UnicodeText(25000), nullable=False)
created_on = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
modified_at = Column(DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
author = relationship('User')
repo = relationship('Repository')
# status_change is frequently used directly in templates - make it a lazy
# join to avoid fetching each related ChangesetStatus on demand.
# There will only be one ChangesetStatus referencing each comment so the join will not explode.
status_change = relationship('ChangesetStatus',
cascade="all, delete-orphan", lazy='joined')
pull_request = relationship('PullRequest')
def get_users(cls, revision=None, pull_request_id=None):
Returns user associated with this ChangesetComment. ie those
who actually commented
:param cls:
:param revision:
Status change: