comparison mercurial/transaction.py @ 49993:2f348babe30d

transaction: clarify the "quick abort" scenario Right now, the transaction has a code-pass to do a "quick abort" that skip most¹ (too much) of the logic when the right condition are detected² We are about to improve this logic in multiple aspect. We clarify the code first. The conditional return in `_can_quick_abort` looks a bit weird because we are about to make them more complex very soon. [1] actually too much [2] actually not often enough
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 14 Feb 2023 18:59:04 +0100
parents 2e726c934fcd
children 3128018e878b
comparison
equal deleted inserted replaced
49992:420fad6bdec5 49993:2f348babe30d
666 self._count = 0 666 self._count = 0
667 self._usages = 0 667 self._usages = 0
668 self._file.close() 668 self._file.close()
669 self._backupsfile.close() 669 self._backupsfile.close()
670 670
671 quick = self._can_quick_abort(entries)
671 try: 672 try:
672 if not entries and not self._backupentries: 673 if quick:
673 if self._backupjournal: 674 self._do_quick_abort(entries)
674 self._opener.unlink(self._backupjournal) 675 else:
675 if self._journal: 676 self._do_full_abort(entries)
676 self._opener.unlink(self._journal)
677 return
678
679 self._report(_(b"transaction abort!\n"))
680
681 try:
682 for cat in sorted(self._abortcallback):
683 self._abortcallback[cat](self)
684 # Prevent double usage and help clear cycles.
685 self._abortcallback = None
686 _playback(
687 self._journal,
688 self._report,
689 self._opener,
690 self._vfsmap,
691 entries,
692 self._backupentries,
693 False,
694 checkambigfiles=self._checkambigfiles,
695 )
696 self._report(_(b"rollback completed\n"))
697 except BaseException as exc:
698 self._report(_(b"rollback failed - please run hg recover\n"))
699 self._report(
700 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
701 )
702 finally: 677 finally:
703 self._journal = None 678 self._journal = None
704 self._releasefn(self, False) # notify failure of transaction 679 self._releasefn(self, False) # notify failure of transaction
705 self._releasefn = None # Help prevent cycles. 680 self._releasefn = None # Help prevent cycles.
681
682 def _can_quick_abort(self, entries):
683 """False if any semantic content have been written on disk
684
685 True if nothing, except temporary files has been writen on disk."""
686 if entries:
687 return False
688 if self._backupentries:
689 return False
690 return True
691
692 def _do_quick_abort(self, entries):
693 """(Silently) do a quick cleanup (see _can_quick_abort)"""
694 assert self._can_quick_abort(entries)
695 if self._backupjournal:
696 self._opener.unlink(self._backupjournal)
697 if self._journal:
698 self._opener.unlink(self._journal)
699
700 def _do_full_abort(self, entries):
701 """(Noisily) rollback all the change introduced by the transaction"""
702 self._report(_(b"transaction abort!\n"))
703 try:
704 for cat in sorted(self._abortcallback):
705 self._abortcallback[cat](self)
706 # Prevent double usage and help clear cycles.
707 self._abortcallback = None
708 _playback(
709 self._journal,
710 self._report,
711 self._opener,
712 self._vfsmap,
713 entries,
714 self._backupentries,
715 False,
716 checkambigfiles=self._checkambigfiles,
717 )
718 self._report(_(b"rollback completed\n"))
719 except BaseException as exc:
720 self._report(_(b"rollback failed - please run hg recover\n"))
721 self._report(
722 _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
723 )
706 724
707 725
708 BAD_VERSION_MSG = _( 726 BAD_VERSION_MSG = _(
709 b"journal was created by a different version of Mercurial\n" 727 b"journal was created by a different version of Mercurial\n"
710 ) 728 )