[PATCH 2 of 5 STABLE] transaction: separate calculating TXNID from creating transaction object

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Tue May 19 10:39:32 CDT 2015


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1432049572 -32400
#      Wed May 20 00:32:52 2015 +0900
# Branch stable
# Node ID ae2915053ec6ee06c64482fba7ba668ce91305e1
# Parent  11f3cae961f815ee7f8acc4e0312ed724d4ef8fe
transaction: separate calculating TXNID from creating transaction object

Before this patch, transaction ID (TXNID) is calculated from
`transaction` object itself, but this prevents TXNID from being passed
to `pretxnopen` hooks, which should be executed before starting
transaction processing (also any preparations for it, like writing
journal files out).

As a preparation for passing TXNID to `pretxnopen` hooks, this patch
separates calculation of TXNID from creation of `transaction` object.

To keep uniqueness of assigned TXNID (= prevent `idobj` from being
reused at another `txnid()` invocation) while corresponded
`transaction` object is alive, this patch also adds `_txnid` field to
`transaction` and makes it refer the tuple returned by `txnid()`.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -960,6 +960,7 @@
                 _("abandoned transaction found"),
                 hint=_("run 'hg recover' to clean up transaction"))
 
+        txnid = transaction.txnid()
         self.hook('pretxnopen', throw=True, txnname=desc)
 
         self._writejournal(desc)
@@ -982,10 +983,9 @@
                                      "undo",
                                      aftertrans(renames),
                                      self.store.createmode,
-                                     validator=validate)
-
-        trid = 'TXN:' + util.sha1("%s#%f" % (id(tr), time.time())).hexdigest()
-        tr.hookargs['TXNID'] = trid
+                                     validator=validate, txnid=txnid)
+
+        tr.hookargs['TXNID'] = txnid[0]
         # note: writing the fncache only during finalize mean that the file is
         # outdated when running hooks. As fncache is used for streaming clone,
         # this is not expected to break anything that happen during the hooks.
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -12,7 +12,7 @@
 # GNU General Public License version 2 or any later version.
 
 from i18n import _
-import errno
+import errno, time
 import error, util
 
 version = 2
@@ -81,9 +81,26 @@
         # only pure backup file remains, it is sage to ignore any error
         pass
 
+def txnid():
+    """Assign unique ID string for transaction
+
+    This returns the tuple of `(TXNID, idinfo)`. `TXNID` can be used
+    as unique transaction ID. (`idinfo` is only for internal
+    use. don't touch it).
+
+    This tuple should be passed to the constructor of `transaction()`
+    via `txnid` argument, to keep uniqueness of assigned `TXNID` while
+    that `transaction` object is alive.
+    """
+    idobj = object()
+    idtime = time.time()
+    return ('TXN:' + util.sha1("%s#%f" % (id(idobj), idtime)).hexdigest(),
+            (idobj, idtime))
+
 class transaction(object):
     def __init__(self, report, opener, vfsmap, journalname, undoname=None,
-                 after=None, createmode=None, validator=None):
+                 after=None, createmode=None, validator=None,
+                 txnid=None):
         """Begin a new transaction
 
         Begins a new transaction that allows rolling back writes in the event of
@@ -146,6 +163,8 @@
         # holds callbacks to call during abort
         self._abortcallback = {}
 
+        self._txnid = txnid
+
     def __del__(self):
         if self.journal:
             self._abort()


More information about the Mercurial-devel mailing list