diff options
Diffstat (limited to 'subcmds/sync.py')
-rw-r--r-- | subcmds/sync.py | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py index e68a025e..a8022d9d 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
@@ -16,6 +16,7 @@ | |||
16 | import netrc | 16 | import netrc |
17 | from optparse import SUPPRESS_HELP | 17 | from optparse import SUPPRESS_HELP |
18 | import os | 18 | import os |
19 | import pickle | ||
19 | import re | 20 | import re |
20 | import shutil | 21 | import shutil |
21 | import socket | 22 | import socket |
@@ -47,6 +48,8 @@ from error import RepoChangedException, GitError | |||
47 | from project import SyncBuffer | 48 | from project import SyncBuffer |
48 | from progress import Progress | 49 | from progress import Progress |
49 | 50 | ||
51 | _ONE_DAY_S = 24 * 60 * 60 | ||
52 | |||
50 | class _FetchError(Exception): | 53 | class _FetchError(Exception): |
51 | """Internal error thrown in _FetchHelper() when we don't want stack trace.""" | 54 | """Internal error thrown in _FetchHelper() when we don't want stack trace.""" |
52 | pass | 55 | pass |
@@ -212,10 +215,12 @@ later is required to fix a server side protocol bug. | |||
212 | # - We always make sure we unlock the lock if we locked it. | 215 | # - We always make sure we unlock the lock if we locked it. |
213 | try: | 216 | try: |
214 | try: | 217 | try: |
218 | start = time.time() | ||
215 | success = project.Sync_NetworkHalf( | 219 | success = project.Sync_NetworkHalf( |
216 | quiet=opt.quiet, | 220 | quiet=opt.quiet, |
217 | current_branch_only=opt.current_branch_only, | 221 | current_branch_only=opt.current_branch_only, |
218 | clone_bundle=not opt.no_clone_bundle) | 222 | clone_bundle=not opt.no_clone_bundle) |
223 | self._fetch_times.Set(project, time.time() - start) | ||
219 | 224 | ||
220 | # Lock around all the rest of the code, since printing, updating a set | 225 | # Lock around all the rest of the code, since printing, updating a set |
221 | # and Progress.update() are not thread safe. | 226 | # and Progress.update() are not thread safe. |
@@ -293,6 +298,7 @@ later is required to fix a server side protocol bug. | |||
293 | sys.exit(1) | 298 | sys.exit(1) |
294 | 299 | ||
295 | pm.end() | 300 | pm.end() |
301 | self._fetch_times.Save() | ||
296 | for project in projects: | 302 | for project in projects: |
297 | project.bare_git.gc('--auto') | 303 | project.bare_git.gc('--auto') |
298 | return fetched | 304 | return fetched |
@@ -496,12 +502,15 @@ uncommitted changes are present' % project.relpath | |||
496 | self.jobs = self.manifest.default.sync_j | 502 | self.jobs = self.manifest.default.sync_j |
497 | all_projects = self.GetProjects(args, missing_ok=True) | 503 | all_projects = self.GetProjects(args, missing_ok=True) |
498 | 504 | ||
505 | self._fetch_times = _FetchTimes(self.manifest) | ||
499 | if not opt.local_only: | 506 | if not opt.local_only: |
500 | to_fetch = [] | 507 | to_fetch = [] |
501 | now = time.time() | 508 | now = time.time() |
502 | if (24 * 60 * 60) <= (now - rp.LastFetch): | 509 | if _ONE_DAY_S <= (now - rp.LastFetch): |
503 | to_fetch.append(rp) | 510 | to_fetch.append(rp) |
504 | to_fetch.extend(all_projects) | 511 | to_fetch.extend(all_projects) |
512 | to_fetch.sort(key=self._fetch_times.Get, reverse=True) | ||
513 | self._fetch_times.Clear() | ||
505 | 514 | ||
506 | self._Fetch(to_fetch, opt) | 515 | self._Fetch(to_fetch, opt) |
507 | _PostRepoFetch(rp, opt.no_repo_verify) | 516 | _PostRepoFetch(rp, opt.no_repo_verify) |
@@ -602,3 +611,53 @@ warning: Cannot automatically authenticate repo.""" | |||
602 | print >>sys.stderr | 611 | print >>sys.stderr |
603 | return False | 612 | return False |
604 | return True | 613 | return True |
614 | |||
615 | class _FetchTimes(object): | ||
616 | def __init__(self, manifest): | ||
617 | self._path = os.path.join(manifest.repodir, '.repopickle_fetchtimes') | ||
618 | self._times = None | ||
619 | |||
620 | def Clear(self): | ||
621 | self._times = {} | ||
622 | |||
623 | def Get(self, project): | ||
624 | self._Load() | ||
625 | return self._times.get(project.name, _ONE_DAY_S) | ||
626 | |||
627 | def Set(self, project, t): | ||
628 | self._times[project.name] = t | ||
629 | |||
630 | def _Load(self): | ||
631 | if self._times is None: | ||
632 | try: | ||
633 | f = open(self._path) | ||
634 | except IOError: | ||
635 | self._times = {} | ||
636 | return self._times | ||
637 | try: | ||
638 | try: | ||
639 | self._times = pickle.load(f) | ||
640 | except: | ||
641 | try: | ||
642 | os.remove(self._path) | ||
643 | except OSError: | ||
644 | pass | ||
645 | self._times = {} | ||
646 | finally: | ||
647 | f.close() | ||
648 | return self._times | ||
649 | |||
650 | def Save(self): | ||
651 | if self._times is None: | ||
652 | return | ||
653 | try: | ||
654 | f = open(self._path, 'wb') | ||
655 | try: | ||
656 | pickle.dump(self._times, f) | ||
657 | except (IOError, OSError, pickle.PickleError): | ||
658 | try: | ||
659 | os.remove(self._path) | ||
660 | except OSError: | ||
661 | pass | ||
662 | finally: | ||
663 | f.close() | ||