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

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sun May 24 16:29:06 UTC 2015


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1432484779 -32400
#      Mon May 25 01:26:19 2015 +0900
# Branch stable
# Node ID 4edea42597e107d8d403e40ac933bf4fd3322b0c
# Parent  fd905b2bea5967c71e71d25f29b2c7a04cafcadc
transaction: separate calculating TXNID from creating transaction object

Before this patch, transaction ID (TXNID) is calculated from
`transaction` object itself by `id()`, 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.

This patch uses "random" library for reasonable unique ID. "uuid"
library can't be used, because it was introduced since Python 2.5 and
isn't suitable for Mercurial 3.4.x stable line.

`%f` formatting for `random.random()` is used with explicit precision
number 40, because default precision for `%f` is 6. 40 should be long
enough, even if 10**9 transactions are executed in a short time (a
second or less).

On the other hand, `time.time()` is used to ensures uniqueness of
TXNID in a long time, for safety.

BTW, platform not providing `/dev/urandom` or so may cause failure of
`import random` itself with some Python versions (see Python
issue15340 for detail http://bugs.python.org/issue15340).

But this patch uses "random" without any workaround, because:

  - "random" is already used directly in some code paths,
  - such platforms are very rare (e.g. Tru64 and HPUX), and
    http://bugs.python.org/issue15340#msg170000
  - updating Python runtime can avoid this issue

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -16,7 +16,7 @@
 import merge as mergemod
 import tags as tagsmod
 from lock import release
-import weakref, errno, os, time, inspect
+import weakref, errno, os, time, inspect, random
 import branchmap, pathutil
 import namespaces
 propertycache = util.propertycache
@@ -960,6 +960,8 @@
                 _("abandoned transaction found"),
                 hint=_("run 'hg recover' to clean up transaction"))
 
+        idbase = "%.40f#%f" % (random.random(), time.time())
+        txnid = 'TXN:' + util.sha1(idbase).hexdigest()
         self.hook('pretxnopen', throw=True, txnname=desc)
 
         self._writejournal(desc)
@@ -984,8 +986,7 @@
                                      self.store.createmode,
                                      validator=validate)
 
-        trid = 'TXN:' + util.sha1("%s#%f" % (id(tr), time.time())).hexdigest()
-        tr.hookargs['txnid'] = trid
+        tr.hookargs['txnid'] = txnid
         # 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.


More information about the Mercurial-devel mailing list