##// END OF EJS Templates
Cached readme generation...
marcink -
r1607:e886f91f beta
parent child Browse files
Show More
@@ -91,21 +91,27 b' beaker.cache.regions=super_short_term,sh'
91
91
92 beaker.cache.super_short_term.type=memory
92 beaker.cache.super_short_term.type=memory
93 beaker.cache.super_short_term.expire=10
93 beaker.cache.super_short_term.expire=10
94 beaker.cache.super_short_term.key_length = 256
94
95
95 beaker.cache.short_term.type=memory
96 beaker.cache.short_term.type=memory
96 beaker.cache.short_term.expire=60
97 beaker.cache.short_term.expire=60
98 beaker.cache.short_term.key_length = 256
97
99
98 beaker.cache.long_term.type=memory
100 beaker.cache.long_term.type=memory
99 beaker.cache.long_term.expire=36000
101 beaker.cache.long_term.expire=36000
102 beaker.cache.long_term.key_length = 256
100
103
101 beaker.cache.sql_cache_short.type=memory
104 beaker.cache.sql_cache_short.type=memory
102 beaker.cache.sql_cache_short.expire=10
105 beaker.cache.sql_cache_short.expire=10
106 beaker.cache.sql_cache_short.key_length = 256
103
107
104 beaker.cache.sql_cache_med.type=memory
108 beaker.cache.sql_cache_med.type=memory
105 beaker.cache.sql_cache_med.expire=360
109 beaker.cache.sql_cache_med.expire=360
110 beaker.cache.sql_cache_med.key_length = 256
106
111
107 beaker.cache.sql_cache_long.type=file
112 beaker.cache.sql_cache_long.type=file
108 beaker.cache.sql_cache_long.expire=3600
113 beaker.cache.sql_cache_long.expire=3600
114 beaker.cache.sql_cache_long.key_length = 256
109
115
110 ####################################
116 ####################################
111 ### BEAKER SESSION ####
117 ### BEAKER SESSION ####
@@ -91,21 +91,27 b' beaker.cache.regions=super_short_term,sh'
91
91
92 beaker.cache.super_short_term.type=memory
92 beaker.cache.super_short_term.type=memory
93 beaker.cache.super_short_term.expire=10
93 beaker.cache.super_short_term.expire=10
94 beaker.cache.super_short_term.key_length = 256
94
95
95 beaker.cache.short_term.type=memory
96 beaker.cache.short_term.type=memory
96 beaker.cache.short_term.expire=60
97 beaker.cache.short_term.expire=60
98 beaker.cache.short_term.key_length = 256
97
99
98 beaker.cache.long_term.type=memory
100 beaker.cache.long_term.type=memory
99 beaker.cache.long_term.expire=36000
101 beaker.cache.long_term.expire=36000
102 beaker.cache.long_term.key_length = 256
100
103
101 beaker.cache.sql_cache_short.type=memory
104 beaker.cache.sql_cache_short.type=memory
102 beaker.cache.sql_cache_short.expire=10
105 beaker.cache.sql_cache_short.expire=10
106 beaker.cache.sql_cache_short.key_length = 256
103
107
104 beaker.cache.sql_cache_med.type=memory
108 beaker.cache.sql_cache_med.type=memory
105 beaker.cache.sql_cache_med.expire=360
109 beaker.cache.sql_cache_med.expire=360
110 beaker.cache.sql_cache_med.key_length = 256
106
111
107 beaker.cache.sql_cache_long.type=file
112 beaker.cache.sql_cache_long.type=file
108 beaker.cache.sql_cache_long.expire=3600
113 beaker.cache.sql_cache_long.expire=3600
114 beaker.cache.sql_cache_long.key_length = 256
109
115
110 ####################################
116 ####################################
111 ### BEAKER SESSION ####
117 ### BEAKER SESSION ####
@@ -91,21 +91,27 b' beaker.cache.regions=super_short_term,sh'
91
91
92 beaker.cache.super_short_term.type=memory
92 beaker.cache.super_short_term.type=memory
93 beaker.cache.super_short_term.expire=10
93 beaker.cache.super_short_term.expire=10
94 beaker.cache.super_short_term.key_length = 256
94
95
95 beaker.cache.short_term.type=memory
96 beaker.cache.short_term.type=memory
96 beaker.cache.short_term.expire=60
97 beaker.cache.short_term.expire=60
98 beaker.cache.short_term.key_length = 256
97
99
98 beaker.cache.long_term.type=memory
100 beaker.cache.long_term.type=memory
99 beaker.cache.long_term.expire=36000
101 beaker.cache.long_term.expire=36000
102 beaker.cache.long_term.key_length = 256
100
103
101 beaker.cache.sql_cache_short.type=memory
104 beaker.cache.sql_cache_short.type=memory
102 beaker.cache.sql_cache_short.expire=10
105 beaker.cache.sql_cache_short.expire=10
106 beaker.cache.sql_cache_short.key_length = 256
103
107
104 beaker.cache.sql_cache_med.type=memory
108 beaker.cache.sql_cache_med.type=memory
105 beaker.cache.sql_cache_med.expire=360
109 beaker.cache.sql_cache_med.expire=360
110 beaker.cache.sql_cache_med.key_length = 256
106
111
107 beaker.cache.sql_cache_long.type=file
112 beaker.cache.sql_cache_long.type=file
108 beaker.cache.sql_cache_long.expire=3600
113 beaker.cache.sql_cache_long.expire=3600
114 beaker.cache.sql_cache_long.key_length = 256
109
115
110 ####################################
116 ####################################
111 ### BEAKER SESSION ####
117 ### BEAKER SESSION ####
@@ -154,6 +160,7 b' sqlalchemy.db1.url = sqlite:///%(here)s/'
154 # MySQL
160 # MySQL
155 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
161 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
156
162
163 # see sqlalchemy docs for others
157
164
158 sqlalchemy.db1.echo = false
165 sqlalchemy.db1.echo = false
159 sqlalchemy.db1.pool_recycle = 3600
166 sqlalchemy.db1.pool_recycle = 3600
@@ -36,7 +36,9 b' from vcs.exceptions import ChangesetErro'
36 from pylons import tmpl_context as c, request, url
36 from pylons import tmpl_context as c, request, url
37 from pylons.i18n.translation import _
37 from pylons.i18n.translation import _
38
38
39 from rhodecode.model.db import Statistics
39 from beaker.cache import cache_region, region_invalidate
40
41 from rhodecode.model.db import Statistics, CacheInvalidation
40 from rhodecode.lib import ALL_READMES, ALL_EXTS
42 from rhodecode.lib import ALL_READMES, ALL_EXTS
41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
43 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
42 from rhodecode.lib.base import BaseRepoController, render
44 from rhodecode.lib.base import BaseRepoController, render
@@ -50,7 +52,7 b' from rhodecode.lib.compat import json, O'
50
52
51 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
52
54
53 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
55 README_FILES = [''.join([x[0][0], x[1][0]]) for x in
54 sorted(list(product(ALL_READMES, ALL_EXTS)),
56 sorted(list(product(ALL_READMES, ALL_EXTS)),
55 key=lambda y:y[0][1] + y[1][1])]
57 key=lambda y:y[0][1] + y[1][1])]
56
58
@@ -166,32 +168,43 b' class SummaryController(BaseRepoControll'
166 if c.enable_downloads:
168 if c.enable_downloads:
167 c.download_options = self._get_download_links(c.rhodecode_repo)
169 c.download_options = self._get_download_links(c.rhodecode_repo)
168
170
169 c.readme_data,c.readme_file = self.__get_readme_data()
171 c.readme_data, c.readme_file = self.__get_readme_data(c.rhodecode_repo)
170 return render('summary/summary.html')
172 return render('summary/summary.html')
171
173
172 def __get_readme_data(self):
174 def __get_readme_data(self, repo):
173 readme_data = None
174 readme_file = None
175
176 try:
177 cs = c.rhodecode_repo.get_changeset('tip')
178 renderer = MarkupRenderer()
179 for f in README_FILES:
180 try:
181 readme = cs.get_node(f)
182 readme_file = f
183 readme_data = renderer.render(readme.content, f)
184 break
185 except NodeDoesNotExistError:
186 continue
187 except ChangesetError:
188 pass
189 except EmptyRepositoryError:
190 pass
191 except Exception:
192 log.error(traceback.format_exc())
193
175
194 return readme_data, readme_file
176 @cache_region('long_term')
177 def _get_readme_from_cache(key):
178 readme_data = None
179 readme_file = None
180 log.debug('Fetching readme file')
181 try:
182 cs = repo.get_changeset('tip')
183 renderer = MarkupRenderer()
184 for f in README_FILES:
185 try:
186 readme = cs.get_node(f)
187 readme_file = f
188 readme_data = renderer.render(readme.content, f)
189 log.debug('Found readme %s' % readme_file)
190 break
191 except NodeDoesNotExistError:
192 continue
193 except ChangesetError:
194 pass
195 except EmptyRepositoryError:
196 pass
197 except Exception:
198 log.error(traceback.format_exc())
199
200 return readme_data, readme_file
201
202 key = repo.name + '_README'
203 inv = CacheInvalidation.invalidate(key)
204 if inv is not None:
205 region_invalidate(_get_readme_from_cache, None, key)
206 CacheInvalidation.set_valid(inv.cache_key)
207 return _get_readme_from_cache(key)
195
208
196 def _get_download_links(self, repo):
209 def _get_download_links(self, repo):
197
210
@@ -663,29 +663,13 b' class Repository(Base, BaseModel):'
663
663
664 @property
664 @property
665 def invalidate(self):
665 def invalidate(self):
666 """
666 return CacheInvalidation.invalidate(self.repo_name)
667 Returns Invalidation object if this repo should be invalidated
668 None otherwise. `cache_active = False` means that this cache
669 state is not valid and needs to be invalidated
670 """
671 return CacheInvalidation.query()\
672 .filter(CacheInvalidation.cache_key == self.repo_name)\
673 .filter(CacheInvalidation.cache_active == False)\
674 .scalar()
675
667
676 def set_invalidate(self):
668 def set_invalidate(self):
677 """
669 """
678 set a cache for invalidation for this instance
670 set a cache for invalidation for this instance
679 """
671 """
680 inv = CacheInvalidation.query()\
672 CacheInvalidation.set_invalidate(self.repo_name)
681 .filter(CacheInvalidation.cache_key == self.repo_name)\
682 .scalar()
683
684 if inv is None:
685 inv = CacheInvalidation(self.repo_name)
686 inv.cache_active = True
687 Session.add(inv)
688 Session.commit()
689
673
690 @LazyProperty
674 @LazyProperty
691 def scm_instance(self):
675 def scm_instance(self):
@@ -696,19 +680,13 b' class Repository(Base, BaseModel):'
696 @cache_region('long_term')
680 @cache_region('long_term')
697 def _c(repo_name):
681 def _c(repo_name):
698 return self.__get_instance()
682 return self.__get_instance()
699
683 rn = self.repo_name
700 # TODO: remove this trick when beaker 1.6 is released
701 # and have fixed this issue with not supporting unicode keys
702 rn = safe_str(self.repo_name)
703
684
704 inv = self.invalidate
685 inv = self.invalidate
705 if inv is not None:
686 if inv is not None:
706 region_invalidate(_c, None, rn)
687 region_invalidate(_c, None, rn)
707 # update our cache
688 # update our cache
708 inv.cache_active = True
689 CacheInvalidation.set_valid(inv.cache_key)
709 Session.add(inv)
710 Session.commit()
711
712 return _c(rn)
690 return _c(rn)
713
691
714 def __get_instance(self):
692 def __get_instance(self):
@@ -730,7 +708,7 b' class Repository(Base, BaseModel):'
730
708
731 repo = backend(safe_str(repo_full_path), create=False,
709 repo = backend(safe_str(repo_full_path), create=False,
732 baseui=self._ui)
710 baseui=self._ui)
733 #skip hidden web repository
711 # skip hidden web repository
734 if repo._get_hidden():
712 if repo._get_hidden():
735 return
713 return
736 else:
714 else:
@@ -855,7 +833,7 b' class Group(Base, BaseModel):'
855
833
856 :param group_name:
834 :param group_name:
857 """
835 """
858 path_prefix = (self.parent_group.full_path_splitted if
836 path_prefix = (self.parent_group.full_path_splitted if
859 self.parent_group else [])
837 self.parent_group else [])
860 return Group.url_sep().join(path_prefix + [group_name])
838 return Group.url_sep().join(path_prefix + [group_name])
861
839
@@ -1060,6 +1038,57 b' class CacheInvalidation(Base, BaseModel)'
1060 return "<%s('%s:%s')>" % (self.__class__.__name__,
1038 return "<%s('%s:%s')>" % (self.__class__.__name__,
1061 self.cache_id, self.cache_key)
1039 self.cache_id, self.cache_key)
1062
1040
1041 @classmethod
1042 def invalidate(cls, key):
1043 """
1044 Returns Invalidation object if this given key should be invalidated
1045 None otherwise. `cache_active = False` means that this cache
1046 state is not valid and needs to be invalidated
1047
1048 :param key:
1049 """
1050 return cls.query()\
1051 .filter(CacheInvalidation.cache_key == key)\
1052 .filter(CacheInvalidation.cache_active == False)\
1053 .scalar()
1054
1055 @classmethod
1056 def set_invalidate(cls, key):
1057 """
1058 Mark this Cache key for invalidation
1059
1060 :param key:
1061 """
1062
1063 log.debug('marking %s for invalidation' % key)
1064 inv_obj = Session().query(cls)\
1065 .filter(cls.cache_key == key).scalar()
1066 if inv_obj:
1067 inv_obj.cache_active = False
1068 else:
1069 log.debug('cache key not found in invalidation db -> creating one')
1070 inv_obj = CacheInvalidation(key)
1071
1072 try:
1073 Session.add(inv_obj)
1074 Session.commit()
1075 except Exception:
1076 log.error(traceback.format_exc())
1077 Session.rollback()
1078
1079 @classmethod
1080 def set_valid(cls, key):
1081 """
1082 Mark this cache key as active and currently cached
1083
1084 :param key:
1085 """
1086 inv_obj = Session().query(CacheInvalidation)\
1087 .filter(CacheInvalidation.cache_key == key).scalar()
1088 inv_obj.cache_active = True
1089 Session.add(inv_obj)
1090 Session.commit()
1091
1063 class DbMigrateVersion(Base, BaseModel):
1092 class DbMigrateVersion(Base, BaseModel):
1064 __tablename__ = 'db_migrate_version'
1093 __tablename__ = 'db_migrate_version'
1065 __table_args__ = {'extend_existing':True}
1094 __table_args__ = {'extend_existing':True}
@@ -197,24 +197,8 b' class ScmModel(BaseModel):'
197
197
198 :param repo_name: this repo that should invalidation take place
198 :param repo_name: this repo that should invalidation take place
199 """
199 """
200
200 CacheInvalidation.set_invalidate(repo_name)
201 log.debug('marking %s for invalidation', repo_name)
201 CacheInvalidation.set_invalidate(repo_name+"_README")
202 cache = self.sa.query(CacheInvalidation)\
203 .filter(CacheInvalidation.cache_key == repo_name).scalar()
204
205 if cache:
206 # mark this cache as inactive
207 cache.cache_active = False
208 else:
209 log.debug('cache key not found in invalidation db -> creating one')
210 cache = CacheInvalidation(repo_name)
211
212 try:
213 self.sa.add(cache)
214 self.sa.commit()
215 except (DatabaseError,):
216 log.error(traceback.format_exc())
217 self.sa.rollback()
218
202
219 def toggle_following_repo(self, follow_repo_id, user_id):
203 def toggle_following_repo(self, follow_repo_id, user_id):
220
204
@@ -395,20 +379,5 b' class ScmModel(BaseModel):'
395
379
396 self.mark_for_invalidation(repo_name)
380 self.mark_for_invalidation(repo_name)
397
381
398
399 def get_unread_journal(self):
382 def get_unread_journal(self):
400 return self.sa.query(UserLog).count()
383 return self.sa.query(UserLog).count()
401
402 def _should_invalidate(self, repo_name):
403 """Looks up database for invalidation signals for this repo_name
404
405 :param repo_name:
406 """
407
408 ret = self.sa.query(CacheInvalidation)\
409 .filter(CacheInvalidation.cache_key == repo_name)\
410 .filter(CacheInvalidation.cache_active == False)\
411 .scalar()
412
413 return ret
414
@@ -88,21 +88,27 b' beaker.cache.regions=super_short_term,sh'
88
88
89 beaker.cache.super_short_term.type=memory
89 beaker.cache.super_short_term.type=memory
90 beaker.cache.super_short_term.expire=10
90 beaker.cache.super_short_term.expire=10
91 beaker.cache.super_short_term.key_length = 256
91
92
92 beaker.cache.short_term.type=memory
93 beaker.cache.short_term.type=memory
93 beaker.cache.short_term.expire=60
94 beaker.cache.short_term.expire=60
95 beaker.cache.short_term.key_length = 256
94
96
95 beaker.cache.long_term.type=memory
97 beaker.cache.long_term.type=memory
96 beaker.cache.long_term.expire=36000
98 beaker.cache.long_term.expire=36000
99 beaker.cache.long_term.key_length = 256
97
100
98 beaker.cache.sql_cache_short.type=memory
101 beaker.cache.sql_cache_short.type=memory
99 beaker.cache.sql_cache_short.expire=10
102 beaker.cache.sql_cache_short.expire=10
103 beaker.cache.sql_cache_short.key_length = 256
100
104
101 beaker.cache.sql_cache_med.type=memory
105 beaker.cache.sql_cache_med.type=memory
102 beaker.cache.sql_cache_med.expire=360
106 beaker.cache.sql_cache_med.expire=360
107 beaker.cache.sql_cache_med.key_length = 256
103
108
104 beaker.cache.sql_cache_long.type=file
109 beaker.cache.sql_cache_long.type=file
105 beaker.cache.sql_cache_long.expire=3600
110 beaker.cache.sql_cache_long.expire=3600
111 beaker.cache.sql_cache_long.key_length = 256
106
112
107 ####################################
113 ####################################
108 ### BEAKER SESSION ####
114 ### BEAKER SESSION ####
@@ -143,7 +149,7 b' logview.pylons.util = #eee'
143 #########################################################
149 #########################################################
144 sqlalchemy.db1.url = sqlite:///%(here)s/test.db
150 sqlalchemy.db1.url = sqlite:///%(here)s/test.db
145 #sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode_tests
151 #sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode_tests
146 #sqlalchemy.db1.echo = False
152 #sqlalchemy.db1.echo = false
147 #sqlalchemy.db1.pool_recycle = 3600
153 #sqlalchemy.db1.pool_recycle = 3600
148 sqlalchemy.convert_unicode = true
154 sqlalchemy.convert_unicode = true
149
155
General Comments 0
You need to be logged in to leave comments. Login now