summaryrefslogtreecommitdiffstats
path: root/subcmds/sync.py
diff options
context:
space:
mode:
authorDave Borowitz <dborowitz@google.com>2012-10-23 16:35:39 -0700
committerDave Borowitz <dborowitz@google.com>2012-10-24 14:52:07 -0700
commitd947858325ae70ff9c0b2f463a9e8c4ffd00002a (patch)
treeedf33164dfdd829eae74244198f790629d2fabc8 /subcmds/sync.py
parent67700e9b90a38cc3719c818bc967153e8b7b429e (diff)
downloadgit-repo-d947858325ae70ff9c0b2f463a9e8c4ffd00002a.tar.gz
sync: Keep a moving average of last fetch times
Try to more accurately estimate which projects take the longest to sync by keeping an exponentially weighted moving average (a=0.5) of fetch times, rather than just recording the last observation. This should discount individual outliers (e.g. an unusually large project update) and hopefully allow truly slow repos to bubble to the top. Change-Id: I72b2508cb1266e8a19cf15b616d8a7fc08098cb3
Diffstat (limited to 'subcmds/sync.py')
-rw-r--r--subcmds/sync.py22
1 files changed, 17 insertions, 5 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py
index a8022d9d..b83f2d4a 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -510,7 +510,6 @@ uncommitted changes are present' % project.relpath
510 to_fetch.append(rp) 510 to_fetch.append(rp)
511 to_fetch.extend(all_projects) 511 to_fetch.extend(all_projects)
512 to_fetch.sort(key=self._fetch_times.Get, reverse=True) 512 to_fetch.sort(key=self._fetch_times.Get, reverse=True)
513 self._fetch_times.Clear()
514 513
515 self._Fetch(to_fetch, opt) 514 self._Fetch(to_fetch, opt)
516 _PostRepoFetch(rp, opt.no_repo_verify) 515 _PostRepoFetch(rp, opt.no_repo_verify)
@@ -613,19 +612,24 @@ warning: Cannot automatically authenticate repo."""
613 return True 612 return True
614 613
615class _FetchTimes(object): 614class _FetchTimes(object):
615 _ALPHA = 0.5
616
616 def __init__(self, manifest): 617 def __init__(self, manifest):
617 self._path = os.path.join(manifest.repodir, '.repopickle_fetchtimes') 618 self._path = os.path.join(manifest.repodir, '.repopickle_fetchtimes')
618 self._times = None 619 self._times = None
619 620 self._seen = set()
620 def Clear(self):
621 self._times = {}
622 621
623 def Get(self, project): 622 def Get(self, project):
624 self._Load() 623 self._Load()
625 return self._times.get(project.name, _ONE_DAY_S) 624 return self._times.get(project.name, _ONE_DAY_S)
626 625
627 def Set(self, project, t): 626 def Set(self, project, t):
628 self._times[project.name] = t 627 self._Load()
628 name = project.name
629 old = self._times.get(name, t)
630 self._seen.add(name)
631 a = self._ALPHA
632 self._times[name] = (a*t) + ((1-a) * old)
629 633
630 def _Load(self): 634 def _Load(self):
631 if self._times is None: 635 if self._times is None:
@@ -650,6 +654,14 @@ class _FetchTimes(object):
650 def Save(self): 654 def Save(self):
651 if self._times is None: 655 if self._times is None:
652 return 656 return
657
658 to_delete = []
659 for name in self._times:
660 if name not in self._seen:
661 to_delete.append(name)
662 for name in to_delete:
663 del self._times[name]
664
653 try: 665 try:
654 f = open(self._path, 'wb') 666 f = open(self._path, 'wb')
655 try: 667 try: