Patchwork [2,of,7,V3] clone: put streaming clones in a transaction

login
register
mail settings
Submitter Durham Goode
Date April 1, 2014, 10:24 p.m.
Message ID <ecb8208fdf2ddb4e237f.1396391052@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/4187/
State Accepted
Commit 925c2d6043890e64c26b2b802a2e681f2464c5b2
Headers show

Comments

Durham Goode - April 1, 2014, 10:24 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1395700700 25200
#      Mon Mar 24 15:38:20 2014 -0700
# Node ID ecb8208fdf2ddb4e237f64d8eb2cc42982c4f050
# Parent  c3f57418b098edc80a693e1ed675f465b843f45a
clone: put streaming clones in a transaction

Streaming clones were writing to files outside of a transaction. Soon the
fncache will be written at transaction close time, so we need streaming clones
to be in a transaction.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2021,26 +2021,36 @@ 
             handled_bytes = 0
             self.ui.progress(_('clone'), 0, total=total_bytes)
             start = time.time()
-            for i in xrange(total_files):
-                # XXX doesn't support '\n' or '\r' in filenames
-                l = fp.readline()
-                try:
-                    name, size = l.split('\0', 1)
-                    size = int(size)
-                except (ValueError, TypeError):
-                    raise error.ResponseError(
-                        _('unexpected response from remote server:'), l)
-                if self.ui.debugflag:
-                    self.ui.debug('adding %s (%s)\n' %
-                                  (name, util.bytecount(size)))
-                # for backwards compat, name was partially encoded
-                ofp = self.sopener(store.decodedir(name), 'w')
-                for chunk in util.filechunkiter(fp, limit=size):
-                    handled_bytes += len(chunk)
-                    self.ui.progress(_('clone'), handled_bytes,
-                                     total=total_bytes)
-                    ofp.write(chunk)
-                ofp.close()
+
+            tr = self.transaction(_('clone'))
+            try:
+                for i in xrange(total_files):
+                    # XXX doesn't support '\n' or '\r' in filenames
+                    l = fp.readline()
+                    try:
+                        name, size = l.split('\0', 1)
+                        size = int(size)
+                    except (ValueError, TypeError):
+                        raise error.ResponseError(
+                            _('unexpected response from remote server:'), l)
+                    if self.ui.debugflag:
+                        self.ui.debug('adding %s (%s)\n' %
+                                      (name, util.bytecount(size)))
+                    # for backwards compat, name was partially encoded
+                    ofp = self.sopener(store.decodedir(name), 'w')
+                    for chunk in util.filechunkiter(fp, limit=size):
+                        handled_bytes += len(chunk)
+                        self.ui.progress(_('clone'), handled_bytes,
+                                         total=total_bytes)
+                        ofp.write(chunk)
+                    ofp.close()
+                tr.close()
+            finally:
+                tr.release()
+
+            # Writing straight to files circumvented the inmemory caches
+            self.invalidate()
+
             elapsed = time.time() - start
             if elapsed <= 0:
                 elapsed = 0.001