comparison mercurial/localrepo.py @ 25267:69c5cab0b893 stable

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
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Mon, 25 May 2015 01:26:19 +0900
parents 2664f536a97e
children a973b050621d
comparison
equal deleted inserted replaced
25266:38117278f295 25267:69c5cab0b893
14 import scmutil, util, extensions, hook, error, revset 14 import scmutil, util, extensions, hook, error, revset
15 import match as matchmod 15 import match as matchmod
16 import merge as mergemod 16 import merge as mergemod
17 import tags as tagsmod 17 import tags as tagsmod
18 from lock import release 18 from lock import release
19 import weakref, errno, os, time, inspect 19 import weakref, errno, os, time, inspect, random
20 import branchmap, pathutil 20 import branchmap, pathutil
21 import namespaces 21 import namespaces
22 propertycache = util.propertycache 22 propertycache = util.propertycache
23 filecache = scmutil.filecache 23 filecache = scmutil.filecache
24 24
958 if self.svfs.exists("journal"): 958 if self.svfs.exists("journal"):
959 raise error.RepoError( 959 raise error.RepoError(
960 _("abandoned transaction found"), 960 _("abandoned transaction found"),
961 hint=_("run 'hg recover' to clean up transaction")) 961 hint=_("run 'hg recover' to clean up transaction"))
962 962
963 idbase = "%.40f#%f" % (random.random(), time.time())
964 txnid = 'TXN:' + util.sha1(idbase).hexdigest()
963 self.hook('pretxnopen', throw=True, txnname=desc) 965 self.hook('pretxnopen', throw=True, txnname=desc)
964 966
965 self._writejournal(desc) 967 self._writejournal(desc)
966 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()] 968 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
967 if report: 969 if report:
982 "undo", 984 "undo",
983 aftertrans(renames), 985 aftertrans(renames),
984 self.store.createmode, 986 self.store.createmode,
985 validator=validate) 987 validator=validate)
986 988
987 trid = 'TXN:' + util.sha1("%s#%f" % (id(tr), time.time())).hexdigest() 989 tr.hookargs['txnid'] = txnid
988 tr.hookargs['txnid'] = trid
989 # note: writing the fncache only during finalize mean that the file is 990 # note: writing the fncache only during finalize mean that the file is
990 # outdated when running hooks. As fncache is used for streaming clone, 991 # outdated when running hooks. As fncache is used for streaming clone,
991 # this is not expected to break anything that happen during the hooks. 992 # this is not expected to break anything that happen during the hooks.
992 tr.addfinalize('flush-fncache', self.store.write) 993 tr.addfinalize('flush-fncache', self.store.write)
993 def txnclosehook(tr2): 994 def txnclosehook(tr2):