Mercurial > hg-stable
changeset 13115:bda5f35fbf67
httpsendfile: record progress information during read()
This allows us to provide deterministic progress information during
transfer of bundle data over HTTP. This is required because we
currently buffer the bundle data to local disk prior to transfer since
wsgiref lacks chunked transfer-coding support.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Fri, 10 Dec 2010 13:31:06 -0600 |
parents | 8f29a08e7bbc |
children | c36dad4f6e54 |
files | mercurial/httprepo.py mercurial/url.py |
diffstat | 2 files changed, 22 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/httprepo.py Tue Dec 07 15:50:28 2010 +0100 +++ b/mercurial/httprepo.py Fri Dec 10 13:31:06 2010 -0600 @@ -160,7 +160,7 @@ break tempname = changegroup.writebundle(cg, None, type) - fp = url.httpsendfile(tempname, "rb") + fp = url.httpsendfile(self.ui, tempname, "rb") headers = {'Content-Type': 'application/mercurial-0.1'} try:
--- a/mercurial/url.py Tue Dec 07 15:50:28 2010 +0100 +++ b/mercurial/url.py Fri Dec 10 13:31:06 2010 -0600 @@ -258,18 +258,36 @@ defines a __len__ attribute to feed the Content-Length header. """ - def __init__(self, *args, **kwargs): + def __init__(self, ui, *args, **kwargs): # We can't just "self._data = open(*args, **kwargs)" here because there # is an "open" function defined in this module that shadows the global # one + self.ui = ui self._data = __builtin__.open(*args, **kwargs) - self.read = self._data.read self.seek = self._data.seek self.close = self._data.close self.write = self._data.write + self._len = os.fstat(self._data.fileno()).st_size + self._pos = 0 + self._total = len(self) / 1024 * 2 + + def read(self, *args, **kwargs): + try: + ret = self._data.read(*args, **kwargs) + except EOFError: + self.ui.progress(_('sending'), None) + self._pos += len(ret) + # We pass double the max for total because we currently have + # to send the bundle twice in the case of a server that + # requires authentication. Since we can't know until we try + # once whether authentication will be required, just lie to + # the user and maybe the push succeeds suddenly at 50%. + self.ui.progress(_('sending'), self._pos / 1024, + unit=_('kb'), total=self._total) + return ret def __len__(self): - return os.fstat(self._data.fileno()).st_size + return self._len def _gen_sendfile(connection): def _sendfile(self, data):