Patchwork D7962: lfs: fix the stall and corruption issue when concurrently uploading blobs

login
register
mail settings
Submitter phabricator
Date Feb. 6, 2020, 10:20 p.m.
Message ID <91ac99c18eddc8ba165a026932866793@localhost.localdomain>
Download mbox | patch
Permalink /patch/45006/
State Not Applicable
Headers show

Comments

phabricator - Feb. 6, 2020, 10:20 p.m.
Closed by commit rHG43eea17ae7b3: lfs: fix the stall and corruption issue when concurrently uploading blobs (authored by mharbison72).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7962?vs=19496&id=19973

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7962/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7962

AFFECTED FILES
  hgext/lfs/blobstore.py

CHANGE DETAILS




To: mharbison72, #hg-reviewers, marmoute
Cc: marmoute, mercurial-devel

Patch

diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py
--- a/hgext/lfs/blobstore.py
+++ b/hgext/lfs/blobstore.py
@@ -21,6 +21,7 @@ 
 from mercurial import (
     encoding,
     error,
+    httpconnection as httpconnectionmod,
     node,
     pathutil,
     pycompat,
@@ -94,28 +95,16 @@ 
         pass
 
 
-class lfsuploadfile(object):
-    """a file-like object that supports __len__ and read.
+class lfsuploadfile(httpconnectionmod.httpsendfile):
+    """a file-like object that supports keepalive.
     """
 
-    def __init__(self, fp):
-        self._fp = fp
-        fp.seek(0, os.SEEK_END)
-        self._len = fp.tell()
-        fp.seek(0)
-
-    def __len__(self):
-        return self._len
+    def __init__(self, ui, filename):
+        super(lfsuploadfile, self).__init__(ui, filename, b'rb')
+        self.read = self._data.read
 
-    def read(self, size):
-        if self._fp is None:
-            return b''
-        return self._fp.read(size)
-
-    def close(self):
-        if self._fp is not None:
-            self._fp.close()
-            self._fp = None
+    def _makeprogress(self):
+        return None  # progress is handled by the worker client
 
 
 class local(object):
@@ -507,10 +496,10 @@ 
 
         try:
             if action == b'upload':
-                request.data = lfsuploadfile(localstore.open(oid))
+                request.data = lfsuploadfile(self.ui, localstore.path(oid))
                 request.get_method = lambda: 'PUT'
                 request.add_header('Content-Type', 'application/octet-stream')
-                request.add_header('Content-Length', len(request.data))
+                request.add_header('Content-Length', request.data.length)
 
             with contextlib.closing(self.urlopener.open(request)) as res:
                 contentlength = res.info().get(b"content-length")