##// END OF EJS Templates
release: Merge default into stable for release preparation
super-admin -
r992:2a5ae811 merge stable
parent child Browse files
Show More
@@ -1,5 +1,5 b''
1 1 [bumpversion]
2 current_version = 4.26.0
2 current_version = 4.27.0
3 3 message = release: Bump version {current_version} to {new_version}
4 4
5 5 [bumpversion:file:vcsserver/VERSION]
@@ -5,12 +5,10 b' done = false'
5 5 done = true
6 6
7 7 [task:fixes_on_stable]
8 done = true
9 8
10 9 [task:pip2nix_generated]
11 done = true
12 10
13 11 [release]
14 state = prepared
15 version = 4.26.0
12 state = in_progress
13 version = 4.27.0
16 14
@@ -784,7 +784,7 b' self: super: {'
784 784 };
785 785 };
786 786 "rhodecode-vcsserver" = super.buildPythonPackage {
787 name = "rhodecode-vcsserver-4.26.0";
787 name = "rhodecode-vcsserver-4.27.0";
788 788 buildInputs = [
789 789 self."pytest"
790 790 self."py"
@@ -1,1 +1,1 b''
1 4.26.0 No newline at end of file
1 4.27.0 No newline at end of file
@@ -23,7 +23,7 b' import urlparse'
23 23 from vcsserver import exceptions
24 24 from vcsserver.exceptions import NoContentException
25 25 from vcsserver.hgcompat import (archival)
26 from vcsserver.lib.rc_cache import region_meta
26
27 27 log = logging.getLogger(__name__)
28 28
29 29
@@ -37,7 +37,7 b' class RepoFactory(object):'
37 37 repo_type = None
38 38
39 39 def __init__(self):
40 self._cache_region = region_meta.dogpile_cache_regions['repo_object']
40 pass
41 41
42 42 def _create_config(self, path, config):
43 43 config = {}
@@ -185,7 +185,8 b' class GitRemote(RemoteBase):'
185 185 @reraise_safe_exceptions
186 186 def assert_correct_path(self, wire):
187 187 cache_on, context_uid, repo_id = self._cache_on(wire)
188 @self.region.conditional_cache_on_arguments(condition=cache_on)
188 region = self._region(wire)
189 @region.conditional_cache_on_arguments(condition=cache_on)
189 190 def _assert_correct_path(_context_uid, _repo_id):
190 191 try:
191 192 repo_init = self._factory.repo_libgit2(wire)
@@ -217,7 +218,8 b' class GitRemote(RemoteBase):'
217 218 @reraise_safe_exceptions
218 219 def blob_raw_length(self, wire, sha):
219 220 cache_on, context_uid, repo_id = self._cache_on(wire)
220 @self.region.conditional_cache_on_arguments(condition=cache_on)
221 region = self._region(wire)
222 @region.conditional_cache_on_arguments(condition=cache_on)
221 223 def _blob_raw_length(_repo_id, _sha):
222 224
223 225 repo_init = self._factory.repo_libgit2(wire)
@@ -248,7 +250,8 b' class GitRemote(RemoteBase):'
248 250 def is_large_file(self, wire, commit_id):
249 251 cache_on, context_uid, repo_id = self._cache_on(wire)
250 252
251 @self.region.conditional_cache_on_arguments(condition=cache_on)
253 region = self._region(wire)
254 @region.conditional_cache_on_arguments(condition=cache_on)
252 255 def _is_large_file(_repo_id, _sha):
253 256 repo_init = self._factory.repo_libgit2(wire)
254 257 with repo_init as repo:
@@ -264,7 +267,8 b' class GitRemote(RemoteBase):'
264 267 def is_binary(self, wire, tree_id):
265 268 cache_on, context_uid, repo_id = self._cache_on(wire)
266 269
267 @self.region.conditional_cache_on_arguments(condition=cache_on)
270 region = self._region(wire)
271 @region.conditional_cache_on_arguments(condition=cache_on)
268 272 def _is_binary(_repo_id, _tree_id):
269 273 repo_init = self._factory.repo_libgit2(wire)
270 274 with repo_init as repo:
@@ -306,7 +310,8 b' class GitRemote(RemoteBase):'
306 310 @reraise_safe_exceptions
307 311 def bulk_request(self, wire, rev, pre_load):
308 312 cache_on, context_uid, repo_id = self._cache_on(wire)
309 @self.region.conditional_cache_on_arguments(condition=cache_on)
313 region = self._region(wire)
314 @region.conditional_cache_on_arguments(condition=cache_on)
310 315 def _bulk_request(_repo_id, _rev, _pre_load):
311 316 result = {}
312 317 for attr in pre_load:
@@ -409,7 +414,8 b' class GitRemote(RemoteBase):'
409 414 @reraise_safe_exceptions
410 415 def branch(self, wire, commit_id):
411 416 cache_on, context_uid, repo_id = self._cache_on(wire)
412 @self.region.conditional_cache_on_arguments(condition=cache_on)
417 region = self._region(wire)
418 @region.conditional_cache_on_arguments(condition=cache_on)
413 419 def _branch(_context_uid, _repo_id, _commit_id):
414 420 regex = re.compile('^refs/heads')
415 421
@@ -424,7 +430,8 b' class GitRemote(RemoteBase):'
424 430 @reraise_safe_exceptions
425 431 def commit_branches(self, wire, commit_id):
426 432 cache_on, context_uid, repo_id = self._cache_on(wire)
427 @self.region.conditional_cache_on_arguments(condition=cache_on)
433 region = self._region(wire)
434 @region.conditional_cache_on_arguments(condition=cache_on)
428 435 def _commit_branches(_context_uid, _repo_id, _commit_id):
429 436 repo_init = self._factory.repo_libgit2(wire)
430 437 with repo_init as repo:
@@ -445,11 +452,22 b' class GitRemote(RemoteBase):'
445 452 # TODO: this is quite complex, check if that can be simplified
446 453 @reraise_safe_exceptions
447 454 def commit(self, wire, commit_data, branch, commit_tree, updated, removed):
455 # Defines the root tree
456 class _Root(object):
457 def __repr__(self):
458 return 'ROOT TREE'
459 ROOT = _Root()
460
448 461 repo = self._factory.repo(wire)
449 462 object_store = repo.object_store
450 463
451 464 # Create tree and populates it with blobs
452 commit_tree = commit_tree and repo[commit_tree] or objects.Tree()
465
466 if commit_tree and repo[commit_tree]:
467 git_commit = repo[commit_data['parents'][0]]
468 commit_tree = repo[git_commit.tree] # root tree
469 else:
470 commit_tree = objects.Tree()
453 471
454 472 for node in updated:
455 473 # Compute subdirs if needed
@@ -508,21 +526,34 b' class GitRemote(RemoteBase):'
508 526
509 527 for node_path in removed:
510 528 paths = node_path.split('/')
511 tree = commit_tree
512 trees = [tree]
529 tree = commit_tree # start with top-level
530 trees = [{'tree': tree, 'path': ROOT}]
513 531 # Traverse deep into the forest...
532 # resolve final tree by iterating the path.
533 # e.g a/b/c.txt will get
534 # - root as tree then
535 # - 'a' as tree,
536 # - 'b' as tree,
537 # - stop at c as blob.
514 538 for path in paths:
515 539 try:
516 540 obj = repo[tree[path][1]]
517 541 if isinstance(obj, objects.Tree):
518 trees.append(obj)
542 trees.append({'tree': obj, 'path': path})
519 543 tree = obj
520 544 except KeyError:
521 545 break
546 #PROBLEM:
547 """
548 We're not editing same reference tree object
549 """
522 550 # Cut down the blob and all rotten trees on the way back...
523 for path, tree in reversed(zip(paths, trees)):
524 del tree[path]
525 if tree:
551 for path, tree_data in reversed(zip(paths, trees)):
552 tree = tree_data['tree']
553 tree.__delitem__(path)
554 # This operation edits the tree, we need to mark new commit back
555
556 if len(tree) > 0:
526 557 # This tree still has elements - don't remove it or any
527 558 # of it's parents
528 559 break
@@ -532,7 +563,7 b' class GitRemote(RemoteBase):'
532 563 # Create commit
533 564 commit = objects.Commit()
534 565 commit.tree = commit_tree.id
535 for k, v in commit_data.iteritems():
566 for k, v in commit_data.items():
536 567 setattr(commit, k, v)
537 568 object_store.add_object(commit)
538 569
@@ -588,7 +619,7 b' class GitRemote(RemoteBase):'
588 619
589 620 if refs and not update_after:
590 621 # mikhail: explicitly set the head to the last ref.
591 repo['HEAD'] = remote_refs[refs[-1]]
622 repo["HEAD"] = remote_refs[refs[-1]]
592 623
593 624 if update_after:
594 625 # we want to checkout HEAD
@@ -690,7 +721,8 b' class GitRemote(RemoteBase):'
690 721 @reraise_safe_exceptions
691 722 def get_object(self, wire, sha, maybe_unreachable=False):
692 723 cache_on, context_uid, repo_id = self._cache_on(wire)
693 @self.region.conditional_cache_on_arguments(condition=cache_on)
724 region = self._region(wire)
725 @region.conditional_cache_on_arguments(condition=cache_on)
694 726 def _get_object(_context_uid, _repo_id, _sha):
695 727 repo_init = self._factory.repo_libgit2(wire)
696 728 with repo_init as repo:
@@ -748,7 +780,8 b' class GitRemote(RemoteBase):'
748 780 @reraise_safe_exceptions
749 781 def get_refs(self, wire):
750 782 cache_on, context_uid, repo_id = self._cache_on(wire)
751 @self.region.conditional_cache_on_arguments(condition=cache_on)
783 region = self._region(wire)
784 @region.conditional_cache_on_arguments(condition=cache_on)
752 785 def _get_refs(_context_uid, _repo_id):
753 786
754 787 repo_init = self._factory.repo_libgit2(wire)
@@ -762,7 +795,8 b' class GitRemote(RemoteBase):'
762 795 @reraise_safe_exceptions
763 796 def get_branch_pointers(self, wire):
764 797 cache_on, context_uid, repo_id = self._cache_on(wire)
765 @self.region.conditional_cache_on_arguments(condition=cache_on)
798 region = self._region(wire)
799 @region.conditional_cache_on_arguments(condition=cache_on)
766 800 def _get_branch_pointers(_context_uid, _repo_id):
767 801
768 802 repo_init = self._factory.repo_libgit2(wire)
@@ -776,7 +810,8 b' class GitRemote(RemoteBase):'
776 810 @reraise_safe_exceptions
777 811 def head(self, wire, show_exc=True):
778 812 cache_on, context_uid, repo_id = self._cache_on(wire)
779 @self.region.conditional_cache_on_arguments(condition=cache_on)
813 region = self._region(wire)
814 @region.conditional_cache_on_arguments(condition=cache_on)
780 815 def _head(_context_uid, _repo_id, _show_exc):
781 816 repo_init = self._factory.repo_libgit2(wire)
782 817 with repo_init as repo:
@@ -801,7 +836,8 b' class GitRemote(RemoteBase):'
801 836 def revision(self, wire, rev):
802 837
803 838 cache_on, context_uid, repo_id = self._cache_on(wire)
804 @self.region.conditional_cache_on_arguments(condition=cache_on)
839 region = self._region(wire)
840 @region.conditional_cache_on_arguments(condition=cache_on)
805 841 def _revision(_context_uid, _repo_id, _rev):
806 842 repo_init = self._factory.repo_libgit2(wire)
807 843 with repo_init as repo:
@@ -819,7 +855,8 b' class GitRemote(RemoteBase):'
819 855 @reraise_safe_exceptions
820 856 def date(self, wire, commit_id):
821 857 cache_on, context_uid, repo_id = self._cache_on(wire)
822 @self.region.conditional_cache_on_arguments(condition=cache_on)
858 region = self._region(wire)
859 @region.conditional_cache_on_arguments(condition=cache_on)
823 860 def _date(_repo_id, _commit_id):
824 861 repo_init = self._factory.repo_libgit2(wire)
825 862 with repo_init as repo:
@@ -838,7 +875,8 b' class GitRemote(RemoteBase):'
838 875 @reraise_safe_exceptions
839 876 def author(self, wire, commit_id):
840 877 cache_on, context_uid, repo_id = self._cache_on(wire)
841 @self.region.conditional_cache_on_arguments(condition=cache_on)
878 region = self._region(wire)
879 @region.conditional_cache_on_arguments(condition=cache_on)
842 880 def _author(_repo_id, _commit_id):
843 881 repo_init = self._factory.repo_libgit2(wire)
844 882 with repo_init as repo:
@@ -862,7 +900,8 b' class GitRemote(RemoteBase):'
862 900 @reraise_safe_exceptions
863 901 def message(self, wire, commit_id):
864 902 cache_on, context_uid, repo_id = self._cache_on(wire)
865 @self.region.conditional_cache_on_arguments(condition=cache_on)
903 region = self._region(wire)
904 @region.conditional_cache_on_arguments(condition=cache_on)
866 905 def _message(_repo_id, _commit_id):
867 906 repo_init = self._factory.repo_libgit2(wire)
868 907 with repo_init as repo:
@@ -873,7 +912,8 b' class GitRemote(RemoteBase):'
873 912 @reraise_safe_exceptions
874 913 def parents(self, wire, commit_id):
875 914 cache_on, context_uid, repo_id = self._cache_on(wire)
876 @self.region.conditional_cache_on_arguments(condition=cache_on)
915 region = self._region(wire)
916 @region.conditional_cache_on_arguments(condition=cache_on)
877 917 def _parents(_repo_id, _commit_id):
878 918 repo_init = self._factory.repo_libgit2(wire)
879 919 with repo_init as repo:
@@ -889,7 +929,8 b' class GitRemote(RemoteBase):'
889 929 @reraise_safe_exceptions
890 930 def children(self, wire, commit_id):
891 931 cache_on, context_uid, repo_id = self._cache_on(wire)
892 @self.region.conditional_cache_on_arguments(condition=cache_on)
932 region = self._region(wire)
933 @region.conditional_cache_on_arguments(condition=cache_on)
893 934 def _children(_repo_id, _commit_id):
894 935 output, __ = self.run_git_command(
895 936 wire, ['rev-list', '--all', '--children'])
@@ -948,7 +989,8 b' class GitRemote(RemoteBase):'
948 989 def tree_and_type_for_path(self, wire, commit_id, path):
949 990
950 991 cache_on, context_uid, repo_id = self._cache_on(wire)
951 @self.region.conditional_cache_on_arguments(condition=cache_on)
992 region = self._region(wire)
993 @region.conditional_cache_on_arguments(condition=cache_on)
952 994 def _tree_and_type_for_path(_context_uid, _repo_id, _commit_id, _path):
953 995 repo_init = self._factory.repo_libgit2(wire)
954 996
@@ -965,7 +1007,8 b' class GitRemote(RemoteBase):'
965 1007 @reraise_safe_exceptions
966 1008 def tree_items(self, wire, tree_id):
967 1009 cache_on, context_uid, repo_id = self._cache_on(wire)
968 @self.region.conditional_cache_on_arguments(condition=cache_on)
1010 region = self._region(wire)
1011 @region.conditional_cache_on_arguments(condition=cache_on)
969 1012 def _tree_items(_repo_id, _tree_id):
970 1013
971 1014 repo_init = self._factory.repo_libgit2(wire)
@@ -1066,7 +1109,8 b' class GitRemote(RemoteBase):'
1066 1109 @reraise_safe_exceptions
1067 1110 def node_history(self, wire, commit_id, path, limit):
1068 1111 cache_on, context_uid, repo_id = self._cache_on(wire)
1069 @self.region.conditional_cache_on_arguments(condition=cache_on)
1112 region = self._region(wire)
1113 @region.conditional_cache_on_arguments(condition=cache_on)
1070 1114 def _node_history(_context_uid, _repo_id, _commit_id, _path, _limit):
1071 1115 # optimize for n==1, rev-list is much faster for that use-case
1072 1116 if limit == 1:
@@ -1108,7 +1152,8 b' class GitRemote(RemoteBase):'
1108 1152 def get_all_commit_ids(self, wire):
1109 1153
1110 1154 cache_on, context_uid, repo_id = self._cache_on(wire)
1111 @self.region.conditional_cache_on_arguments(condition=cache_on)
1155 region = self._region(wire)
1156 @region.conditional_cache_on_arguments(condition=cache_on)
1112 1157 def _get_all_commit_ids(_context_uid, _repo_id):
1113 1158
1114 1159 cmd = ['rev-list', '--reverse', '--date-order', '--branches', '--tags']
@@ -1193,6 +1238,13 b' class GitRemote(RemoteBase):'
1193 1238 }
1194 1239
1195 1240 @reraise_safe_exceptions
1241 def set_head_ref(self, wire, head_name):
1242 log.debug('Setting refs/head to `%s`', head_name)
1243 cmd = ['symbolic-ref', 'HEAD', 'refs/heads/%s' % head_name]
1244 output, __ = self.run_git_command(wire, cmd)
1245 return [head_name] + output.splitlines()
1246
1247 @reraise_safe_exceptions
1196 1248 def archive_repo(self, wire, archive_dest_path, kind, mtime, archive_at_path,
1197 1249 archive_dir_name, commit_id):
1198 1250
@@ -1220,7 +1272,10 b' class GitRemote(RemoteBase):'
1220 1272 file_path = fn.path
1221 1273 mode = fn.mode
1222 1274 is_link = stat.S_ISLNK(mode)
1223 yield ArchiveNode(file_path, mode, is_link, repo[fn.id].read_raw)
1275 if mode == pygit2.GIT_FILEMODE_COMMIT:
1276 log.debug('Skipping path %s as a commit node', file_path)
1277 continue
1278 yield ArchiveNode(file_path, mode, is_link, repo[fn.hex].read_raw)
1224 1279
1225 1280 return archive_repo(file_walker, archive_dest_path, kind, mtime, archive_at_path,
1226 1281 archive_dir_name, commit_id)
@@ -209,7 +209,8 b' class HgRemote(RemoteBase):'
209 209 @reraise_safe_exceptions
210 210 def bookmarks(self, wire):
211 211 cache_on, context_uid, repo_id = self._cache_on(wire)
212 @self.region.conditional_cache_on_arguments(condition=cache_on)
212 region = self._region(wire)
213 @region.conditional_cache_on_arguments(condition=cache_on)
213 214 def _bookmarks(_context_uid, _repo_id):
214 215 repo = self._factory.repo(wire)
215 216 return dict(repo._bookmarks)
@@ -219,7 +220,8 b' class HgRemote(RemoteBase):'
219 220 @reraise_safe_exceptions
220 221 def branches(self, wire, normal, closed):
221 222 cache_on, context_uid, repo_id = self._cache_on(wire)
222 @self.region.conditional_cache_on_arguments(condition=cache_on)
223 region = self._region(wire)
224 @region.conditional_cache_on_arguments(condition=cache_on)
223 225 def _branches(_context_uid, _repo_id, _normal, _closed):
224 226 repo = self._factory.repo(wire)
225 227 iter_branches = repo.branchmap().iterbranches()
@@ -237,7 +239,8 b' class HgRemote(RemoteBase):'
237 239 @reraise_safe_exceptions
238 240 def bulk_request(self, wire, commit_id, pre_load):
239 241 cache_on, context_uid, repo_id = self._cache_on(wire)
240 @self.region.conditional_cache_on_arguments(condition=cache_on)
242 region = self._region(wire)
243 @region.conditional_cache_on_arguments(condition=cache_on)
241 244 def _bulk_request(_repo_id, _commit_id, _pre_load):
242 245 result = {}
243 246 for attr in pre_load:
@@ -254,7 +257,8 b' class HgRemote(RemoteBase):'
254 257 @reraise_safe_exceptions
255 258 def ctx_branch(self, wire, commit_id):
256 259 cache_on, context_uid, repo_id = self._cache_on(wire)
257 @self.region.conditional_cache_on_arguments(condition=cache_on)
260 region = self._region(wire)
261 @region.conditional_cache_on_arguments(condition=cache_on)
258 262 def _ctx_branch(_repo_id, _commit_id):
259 263 repo = self._factory.repo(wire)
260 264 ctx = self._get_ctx(repo, commit_id)
@@ -264,7 +268,8 b' class HgRemote(RemoteBase):'
264 268 @reraise_safe_exceptions
265 269 def ctx_date(self, wire, commit_id):
266 270 cache_on, context_uid, repo_id = self._cache_on(wire)
267 @self.region.conditional_cache_on_arguments(condition=cache_on)
271 region = self._region(wire)
272 @region.conditional_cache_on_arguments(condition=cache_on)
268 273 def _ctx_date(_repo_id, _commit_id):
269 274 repo = self._factory.repo(wire)
270 275 ctx = self._get_ctx(repo, commit_id)
@@ -280,7 +285,8 b' class HgRemote(RemoteBase):'
280 285 @reraise_safe_exceptions
281 286 def ctx_files(self, wire, commit_id):
282 287 cache_on, context_uid, repo_id = self._cache_on(wire)
283 @self.region.conditional_cache_on_arguments(condition=cache_on)
288 region = self._region(wire)
289 @region.conditional_cache_on_arguments(condition=cache_on)
284 290 def _ctx_files(_repo_id, _commit_id):
285 291 repo = self._factory.repo(wire)
286 292 ctx = self._get_ctx(repo, commit_id)
@@ -297,7 +303,8 b' class HgRemote(RemoteBase):'
297 303 @reraise_safe_exceptions
298 304 def ctx_parents(self, wire, commit_id):
299 305 cache_on, context_uid, repo_id = self._cache_on(wire)
300 @self.region.conditional_cache_on_arguments(condition=cache_on)
306 region = self._region(wire)
307 @region.conditional_cache_on_arguments(condition=cache_on)
301 308 def _ctx_parents(_repo_id, _commit_id):
302 309 repo = self._factory.repo(wire)
303 310 ctx = self._get_ctx(repo, commit_id)
@@ -309,7 +316,8 b' class HgRemote(RemoteBase):'
309 316 @reraise_safe_exceptions
310 317 def ctx_children(self, wire, commit_id):
311 318 cache_on, context_uid, repo_id = self._cache_on(wire)
312 @self.region.conditional_cache_on_arguments(condition=cache_on)
319 region = self._region(wire)
320 @region.conditional_cache_on_arguments(condition=cache_on)
313 321 def _ctx_children(_repo_id, _commit_id):
314 322 repo = self._factory.repo(wire)
315 323 ctx = self._get_ctx(repo, commit_id)
@@ -321,7 +329,8 b' class HgRemote(RemoteBase):'
321 329 @reraise_safe_exceptions
322 330 def ctx_phase(self, wire, commit_id):
323 331 cache_on, context_uid, repo_id = self._cache_on(wire)
324 @self.region.conditional_cache_on_arguments(condition=cache_on)
332 region = self._region(wire)
333 @region.conditional_cache_on_arguments(condition=cache_on)
325 334 def _ctx_phase(_context_uid, _repo_id, _commit_id):
326 335 repo = self._factory.repo(wire)
327 336 ctx = self._get_ctx(repo, commit_id)
@@ -332,7 +341,8 b' class HgRemote(RemoteBase):'
332 341 @reraise_safe_exceptions
333 342 def ctx_obsolete(self, wire, commit_id):
334 343 cache_on, context_uid, repo_id = self._cache_on(wire)
335 @self.region.conditional_cache_on_arguments(condition=cache_on)
344 region = self._region(wire)
345 @region.conditional_cache_on_arguments(condition=cache_on)
336 346 def _ctx_obsolete(_context_uid, _repo_id, _commit_id):
337 347 repo = self._factory.repo(wire)
338 348 ctx = self._get_ctx(repo, commit_id)
@@ -342,7 +352,8 b' class HgRemote(RemoteBase):'
342 352 @reraise_safe_exceptions
343 353 def ctx_hidden(self, wire, commit_id):
344 354 cache_on, context_uid, repo_id = self._cache_on(wire)
345 @self.region.conditional_cache_on_arguments(condition=cache_on)
355 region = self._region(wire)
356 @region.conditional_cache_on_arguments(condition=cache_on)
346 357 def _ctx_hidden(_context_uid, _repo_id, _commit_id):
347 358 repo = self._factory.repo(wire)
348 359 ctx = self._get_ctx(repo, commit_id)
@@ -455,7 +466,8 b' class HgRemote(RemoteBase):'
455 466 @reraise_safe_exceptions
456 467 def node_history(self, wire, revision, path, limit):
457 468 cache_on, context_uid, repo_id = self._cache_on(wire)
458 @self.region.conditional_cache_on_arguments(condition=cache_on)
469 region = self._region(wire)
470 @region.conditional_cache_on_arguments(condition=cache_on)
459 471 def _node_history(_context_uid, _repo_id, _revision, _path, _limit):
460 472 repo = self._factory.repo(wire)
461 473
@@ -485,7 +497,8 b' class HgRemote(RemoteBase):'
485 497 @reraise_safe_exceptions
486 498 def node_history_untill(self, wire, revision, path, limit):
487 499 cache_on, context_uid, repo_id = self._cache_on(wire)
488 @self.region.conditional_cache_on_arguments(condition=cache_on)
500 region = self._region(wire)
501 @region.conditional_cache_on_arguments(condition=cache_on)
489 502 def _node_history_until(_context_uid, _repo_id):
490 503 repo = self._factory.repo(wire)
491 504 ctx = self._get_ctx(repo, revision)
@@ -523,7 +536,8 b' class HgRemote(RemoteBase):'
523 536 @reraise_safe_exceptions
524 537 def fctx_flags(self, wire, commit_id, path):
525 538 cache_on, context_uid, repo_id = self._cache_on(wire)
526 @self.region.conditional_cache_on_arguments(condition=cache_on)
539 region = self._region(wire)
540 @region.conditional_cache_on_arguments(condition=cache_on)
527 541 def _fctx_flags(_repo_id, _commit_id, _path):
528 542 repo = self._factory.repo(wire)
529 543 ctx = self._get_ctx(repo, commit_id)
@@ -535,7 +549,8 b' class HgRemote(RemoteBase):'
535 549 @reraise_safe_exceptions
536 550 def fctx_size(self, wire, commit_id, path):
537 551 cache_on, context_uid, repo_id = self._cache_on(wire)
538 @self.region.conditional_cache_on_arguments(condition=cache_on)
552 region = self._region(wire)
553 @region.conditional_cache_on_arguments(condition=cache_on)
539 554 def _fctx_size(_repo_id, _revision, _path):
540 555 repo = self._factory.repo(wire)
541 556 ctx = self._get_ctx(repo, commit_id)
@@ -546,7 +561,8 b' class HgRemote(RemoteBase):'
546 561 @reraise_safe_exceptions
547 562 def get_all_commit_ids(self, wire, name):
548 563 cache_on, context_uid, repo_id = self._cache_on(wire)
549 @self.region.conditional_cache_on_arguments(condition=cache_on)
564 region = self._region(wire)
565 @region.conditional_cache_on_arguments(condition=cache_on)
550 566 def _get_all_commit_ids(_context_uid, _repo_id, _name):
551 567 repo = self._factory.repo(wire)
552 568 repo = repo.filtered(name)
@@ -562,7 +578,8 b' class HgRemote(RemoteBase):'
562 578 @reraise_safe_exceptions
563 579 def is_large_file(self, wire, commit_id, path):
564 580 cache_on, context_uid, repo_id = self._cache_on(wire)
565 @self.region.conditional_cache_on_arguments(condition=cache_on)
581 region = self._region(wire)
582 @region.conditional_cache_on_arguments(condition=cache_on)
566 583 def _is_large_file(_context_uid, _repo_id, _commit_id, _path):
567 584 return largefiles.lfutil.isstandin(path)
568 585
@@ -572,7 +589,8 b' class HgRemote(RemoteBase):'
572 589 def is_binary(self, wire, revision, path):
573 590 cache_on, context_uid, repo_id = self._cache_on(wire)
574 591
575 @self.region.conditional_cache_on_arguments(condition=cache_on)
592 region = self._region(wire)
593 @region.conditional_cache_on_arguments(condition=cache_on)
576 594 def _is_binary(_repo_id, _sha, _path):
577 595 repo = self._factory.repo(wire)
578 596 ctx = self._get_ctx(repo, revision)
@@ -610,7 +628,8 b' class HgRemote(RemoteBase):'
610 628 def lookup(self, wire, revision, both):
611 629 cache_on, context_uid, repo_id = self._cache_on(wire)
612 630
613 @self.region.conditional_cache_on_arguments(condition=cache_on)
631 region = self._region(wire)
632 @region.conditional_cache_on_arguments(condition=cache_on)
614 633 def _lookup(_context_uid, _repo_id, _revision, _both):
615 634
616 635 repo = self._factory.repo(wire)
@@ -668,7 +687,8 b' class HgRemote(RemoteBase):'
668 687 def rev_range(self, wire, commit_filter):
669 688 cache_on, context_uid, repo_id = self._cache_on(wire)
670 689
671 @self.region.conditional_cache_on_arguments(condition=cache_on)
690 region = self._region(wire)
691 @region.conditional_cache_on_arguments(condition=cache_on)
672 692 def _rev_range(_context_uid, _repo_id, _filter):
673 693 repo = self._factory.repo(wire)
674 694 revisions = [rev for rev in revrange(repo, commit_filter)]
@@ -743,7 +763,8 b' class HgRemote(RemoteBase):'
743 763 @reraise_safe_exceptions
744 764 def tags(self, wire):
745 765 cache_on, context_uid, repo_id = self._cache_on(wire)
746 @self.region.conditional_cache_on_arguments(condition=cache_on)
766 region = self._region(wire)
767 @region.conditional_cache_on_arguments(condition=cache_on)
747 768 def _tags(_context_uid, _repo_id):
748 769 repo = self._factory.repo(wire)
749 770 return repo.tags()
@@ -996,6 +1017,10 b' class HgRemote(RemoteBase):'
996 1017 }
997 1018
998 1019 @reraise_safe_exceptions
1020 def set_head_ref(self, wire, head_name):
1021 pass
1022
1023 @reraise_safe_exceptions
999 1024 def archive_repo(self, wire, archive_dest_path, kind, mtime, archive_at_path,
1000 1025 archive_dir_name, commit_id):
1001 1026
@@ -49,7 +49,7 b' class HooksHttpClient(object):'
49 49 try:
50 50 connection.request('POST', '/', body)
51 51 except Exception:
52 log.error('Connection failed on %s', connection)
52 log.error('Hooks calling Connection failed on %s', connection.__dict__)
53 53 raise
54 54 response = connection.getresponse()
55 55
@@ -394,7 +394,7 b' class HTTPApplication(object):'
394 394 else:
395 395 call_args = args[1:]
396 396
397 log.debug('method requested:%s with args:%s kwargs:%s context_uid: %s, repo_state_uid:%s',
397 log.debug('Method requested:`%s` with args:%s kwargs:%s context_uid: %s, repo_state_uid:%s',
398 398 method, call_args, kwargs, context_uid, repo_state_uid)
399 399
400 400 return payload, remote, method, args, kwargs
@@ -38,7 +38,9 b' register_backend('
38 38 log = logging.getLogger(__name__)
39 39
40 40 from . import region_meta
41 from .utils import (get_default_cache_settings, backend_key_generator, make_region)
41 from .utils import (
42 get_default_cache_settings, backend_key_generator, get_or_create_region,
43 clear_cache_namespace, make_region)
42 44
43 45
44 46 def configure_dogpile_cache(settings):
@@ -32,6 +32,7 b' from dogpile.cache.util import memoized_'
32 32 from pyramid.settings import asbool
33 33
34 34 from vcsserver.lib.memory_lru_dict import LRUDict, LRUDictDebug
35 from vcsserver.utils import safe_str
35 36
36 37
37 38 _default_max_size = 1024
@@ -264,7 +265,7 b' class BaseRedisBackend(redis_backend.Red'
264 265
265 266 def get_mutex(self, key):
266 267 if self.distributed_lock:
267 lock_key = redis_backend.u('_lock_{0}').format(key)
268 lock_key = redis_backend.u('_lock_{0}').format(safe_str(key))
268 269 return get_mutex_lock(self.client, lock_key, self._lock_timeout,
269 270 auto_renewal=self._lock_auto_renewal)
270 271 else:
@@ -16,17 +16,16 b''
16 16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 17
18 18 import os
19 import time
19 20 import logging
20 21 import functools
21 import time
22
23 from decorator import decorate
24 22
25 23 from dogpile.cache import CacheRegion
26 24 from dogpile.cache.util import compat
27 25
28 26 from vcsserver.utils import safe_str, sha1
29 27
28 from vcsserver.lib.rc_cache import region_meta
30 29
31 30 log = logging.getLogger(__name__)
32 31
@@ -50,14 +49,69 b' class RhodeCodeCacheRegion(CacheRegion):'
50 49 if function_key_generator is None:
51 50 function_key_generator = self.function_key_generator
52 51
52 # workaround for py2 and cython problems, this block should be removed
53 # once we've migrated to py3
54 if 'cython' == 'cython':
55 def decorator(fn):
56 if to_str is compat.string_type:
57 # backwards compatible
58 key_generator = function_key_generator(namespace, fn)
59 else:
60 key_generator = function_key_generator(namespace, fn, to_str=to_str)
61
62 @functools.wraps(fn)
63 def decorate(*arg, **kw):
64 key = key_generator(*arg, **kw)
65
66 @functools.wraps(fn)
67 def creator():
68 return fn(*arg, **kw)
69
70 if not condition:
71 return creator()
72
73 timeout = expiration_time() if expiration_time_is_callable \
74 else expiration_time
75
76 return self.get_or_create(key, creator, timeout, should_cache_fn)
77
78 def invalidate(*arg, **kw):
79 key = key_generator(*arg, **kw)
80 self.delete(key)
81
82 def set_(value, *arg, **kw):
83 key = key_generator(*arg, **kw)
84 self.set(key, value)
85
86 def get(*arg, **kw):
87 key = key_generator(*arg, **kw)
88 return self.get(key)
89
90 def refresh(*arg, **kw):
91 key = key_generator(*arg, **kw)
92 value = fn(*arg, **kw)
93 self.set(key, value)
94 return value
95
96 decorate.set = set_
97 decorate.invalidate = invalidate
98 decorate.refresh = refresh
99 decorate.get = get
100 decorate.original = fn
101 decorate.key_generator = key_generator
102 decorate.__wrapped__ = fn
103
104 return decorate
105 return decorator
106
53 107 def get_or_create_for_user_func(key_generator, user_func, *arg, **kw):
54 108
55 109 if not condition:
56 log.debug('Calling un-cached func:%s', user_func.func_name)
110 log.debug('Calling un-cached method:%s', user_func.func_name)
57 111 start = time.time()
58 112 result = user_func(*arg, **kw)
59 113 total = time.time() - start
60 log.debug('un-cached func:%s took %.4fs', user_func.func_name, total)
114 log.debug('un-cached method:%s took %.4fs', user_func.func_name, total)
61 115 return result
62 116
63 117 key = key_generator(*arg, **kw)
@@ -65,7 +119,7 b' class RhodeCodeCacheRegion(CacheRegion):'
65 119 timeout = expiration_time() if expiration_time_is_callable \
66 120 else expiration_time
67 121
68 log.debug('Calling cached fn:%s', user_func.func_name)
122 log.debug('Calling cached method:`%s`', user_func.func_name)
69 123 return self.get_or_create(key, user_func, timeout, should_cache_fn, (arg, kw))
70 124
71 125 def cache_decorator(user_func):
@@ -104,7 +158,7 b' class RhodeCodeCacheRegion(CacheRegion):'
104 158 user_func.original = user_func
105 159
106 160 # Use `decorate` to preserve the signature of :param:`user_func`.
107 return decorate(user_func, functools.partial(
161 return decorator.decorate(user_func, functools.partial(
108 162 get_or_create_for_user_func, key_generator))
109 163
110 164 return cache_decorator
@@ -156,3 +210,54 b' def key_generator(backend, namespace, fn'
156 210 return final_key
157 211
158 212 return generate_key
213
214
215 def get_or_create_region(region_name, region_namespace=None):
216 from vcsserver.lib.rc_cache.backends import FileNamespaceBackend
217 region_obj = region_meta.dogpile_cache_regions.get(region_name)
218 if not region_obj:
219 raise EnvironmentError(
220 'Region `{}` not in configured: {}.'.format(
221 region_name, region_meta.dogpile_cache_regions.keys()))
222
223 region_uid_name = '{}:{}'.format(region_name, region_namespace)
224 if isinstance(region_obj.actual_backend, FileNamespaceBackend):
225 region_exist = region_meta.dogpile_cache_regions.get(region_namespace)
226 if region_exist:
227 log.debug('Using already configured region: %s', region_namespace)
228 return region_exist
229 cache_dir = region_meta.dogpile_config_defaults['cache_dir']
230 expiration_time = region_obj.expiration_time
231
232 if not os.path.isdir(cache_dir):
233 os.makedirs(cache_dir)
234 new_region = make_region(
235 name=region_uid_name,
236 function_key_generator=backend_key_generator(region_obj.actual_backend)
237 )
238 namespace_filename = os.path.join(
239 cache_dir, "{}.cache.dbm".format(region_namespace))
240 # special type that allows 1db per namespace
241 new_region.configure(
242 backend='dogpile.cache.rc.file_namespace',
243 expiration_time=expiration_time,
244 arguments={"filename": namespace_filename}
245 )
246
247 # create and save in region caches
248 log.debug('configuring new region: %s', region_uid_name)
249 region_obj = region_meta.dogpile_cache_regions[region_namespace] = new_region
250
251 return region_obj
252
253
254 def clear_cache_namespace(cache_region, cache_namespace_uid, invalidate=False):
255 region = get_or_create_region(cache_region, cache_namespace_uid)
256 cache_keys = region.backend.list_keys(prefix=cache_namespace_uid)
257 num_delete_keys = len(cache_keys)
258 if invalidate:
259 region.invalidate(hard=False)
260 else:
261 if num_delete_keys:
262 region.delete_multi(cache_keys)
263 return num_delete_keys
@@ -201,7 +201,8 b' class SvnRemote(RemoteBase):'
201 201 def revision_properties(self, wire, revision):
202 202
203 203 cache_on, context_uid, repo_id = self._cache_on(wire)
204 @self.region.conditional_cache_on_arguments(condition=cache_on)
204 region = self._region(wire)
205 @region.conditional_cache_on_arguments(condition=cache_on)
205 206 def _revision_properties(_repo_id, _revision):
206 207 repo = self._factory.repo(wire)
207 208 fs_ptr = svn.repos.fs(repo)
@@ -255,7 +256,8 b' class SvnRemote(RemoteBase):'
255 256 @reraise_safe_exceptions
256 257 def node_history(self, wire, path, revision, limit):
257 258 cache_on, context_uid, repo_id = self._cache_on(wire)
258 @self.region.conditional_cache_on_arguments(condition=cache_on)
259 region = self._region(wire)
260 @region.conditional_cache_on_arguments(condition=cache_on)
259 261 def _assert_correct_path(_context_uid, _repo_id, _path, _revision, _limit):
260 262 cross_copies = False
261 263 repo = self._factory.repo(wire)
@@ -276,7 +278,8 b' class SvnRemote(RemoteBase):'
276 278
277 279 def node_properties(self, wire, path, revision):
278 280 cache_on, context_uid, repo_id = self._cache_on(wire)
279 @self.region.conditional_cache_on_arguments(condition=cache_on)
281 region = self._region(wire)
282 @region.conditional_cache_on_arguments(condition=cache_on)
280 283 def _node_properties(_repo_id, _path, _revision):
281 284 repo = self._factory.repo(wire)
282 285 fsobj = svn.repos.fs(repo)
@@ -314,7 +317,8 b' class SvnRemote(RemoteBase):'
314 317 def get_node_type(self, wire, path, revision=None):
315 318
316 319 cache_on, context_uid, repo_id = self._cache_on(wire)
317 @self.region.conditional_cache_on_arguments(condition=cache_on)
320 region = self._region(wire)
321 @region.conditional_cache_on_arguments(condition=cache_on)
318 322 def _get_node_type(_repo_id, _path, _revision):
319 323 repo = self._factory.repo(wire)
320 324 fs_ptr = svn.repos.fs(repo)
@@ -328,7 +332,8 b' class SvnRemote(RemoteBase):'
328 332 def get_nodes(self, wire, path, revision=None):
329 333
330 334 cache_on, context_uid, repo_id = self._cache_on(wire)
331 @self.region.conditional_cache_on_arguments(condition=cache_on)
335 region = self._region(wire)
336 @region.conditional_cache_on_arguments(condition=cache_on)
332 337 def _get_nodes(_repo_id, _path, _revision):
333 338 repo = self._factory.repo(wire)
334 339 fsobj = svn.repos.fs(repo)
@@ -355,7 +360,8 b' class SvnRemote(RemoteBase):'
355 360 def get_file_size(self, wire, path, revision=None):
356 361
357 362 cache_on, context_uid, repo_id = self._cache_on(wire)
358 @self.region.conditional_cache_on_arguments(condition=cache_on)
363 region = self._region(wire)
364 @region.conditional_cache_on_arguments(condition=cache_on)
359 365 def _get_file_size(_repo_id, _path, _revision):
360 366 repo = self._factory.repo(wire)
361 367 fsobj = svn.repos.fs(repo)
@@ -470,7 +476,8 b' class SvnRemote(RemoteBase):'
470 476 def is_binary(self, wire, rev, path):
471 477 cache_on, context_uid, repo_id = self._cache_on(wire)
472 478
473 @self.region.conditional_cache_on_arguments(condition=cache_on)
479 region = self._region(wire)
480 @region.conditional_cache_on_arguments(condition=cache_on)
474 481 def _is_binary(_repo_id, _rev, _path):
475 482 raw_bytes = self.get_file_content(wire, path, rev)
476 483 return raw_bytes and '\0' in raw_bytes
@@ -530,6 +537,10 b' class SvnRemote(RemoteBase):'
530 537 }
531 538
532 539 @reraise_safe_exceptions
540 def set_head_ref(self, wire, head_name):
541 pass
542
543 @reraise_safe_exceptions
533 544 def archive_repo(self, wire, archive_dest_path, kind, mtime, archive_at_path,
534 545 archive_dir_name, commit_id):
535 546
@@ -113,7 +113,7 b' class TestReraiseSafeExceptions(object):'
113 113
114 114 methods = inspect.getmembers(git_remote, predicate=inspect.ismethod)
115 115 for method_name, method in methods:
116 if not method_name.startswith('_'):
116 if not method_name.startswith('_') and method_name not in ['vcsserver_invalidate_cache']:
117 117 assert method.im_func.__code__ == decorator.__code__
118 118
119 119 @pytest.mark.parametrize('side_effect, expected_type', [
@@ -50,7 +50,7 b' class TestReraiseSafeExceptions(object):'
50 50 methods = inspect.getmembers(hg_remote, predicate=inspect.ismethod)
51 51 decorator = hg.reraise_safe_exceptions(None)
52 52 for method_name, method in methods:
53 if not method_name.startswith('_'):
53 if not method_name.startswith('_') and method_name not in ['vcsserver_invalidate_cache']:
54 54 assert method.im_func.__code__ == decorator.__code__
55 55
56 56 @pytest.mark.parametrize('side_effect, expected_type', [
@@ -15,13 +15,15 b''
15 15 # along with this program; if not, write to the Free Software Foundation,
16 16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 17
18 from vcsserver.lib import rc_cache
18 19
19 20 class RemoteBase(object):
20 21 EMPTY_COMMIT = '0' * 40
21 22
22 @property
23 def region(self):
24 return self._factory._cache_region
23 def _region(self, wire):
24 repo_id = wire.get('repo_id', '')
25 cache_namespace_uid = 'cache_repo.{}'.format(repo_id)
26 return rc_cache.get_or_create_region('repo_object', cache_namespace_uid)
25 27
26 28 def _cache_on(self, wire):
27 29 context = wire.get('context', '')
@@ -30,3 +32,14 b' class RemoteBase(object):'
30 32 cache = wire.get('cache', True)
31 33 cache_on = context and cache
32 34 return cache_on, context_uid, repo_id
35
36 def vcsserver_invalidate_cache(self, wire, delete):
37 from vcsserver.lib import rc_cache
38 repo_id = wire.get('repo_id', '')
39
40 if delete:
41 cache_namespace_uid = 'cache_repo.{}'.format(repo_id)
42 rc_cache.clear_cache_namespace(
43 'repo_object', cache_namespace_uid, invalidate=True)
44
45 return {'invalidated': {'repo_id': repo_id, 'delete': delete}}
General Comments 0
You need to be logged in to leave comments. Login now