Mercurial > public > mercurial-scm > hg
comparison mercurial/url.py @ 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 | ae163a0a3cd0 |
children | b75fc70f0a9f |
comparison
equal
deleted
inserted
replaced
13114:8f29a08e7bbc | 13115:bda5f35fbf67 |
---|---|
256 | 256 |
257 Its purpose is to send file-like objects via HTTP and, to do so, it | 257 Its purpose is to send file-like objects via HTTP and, to do so, it |
258 defines a __len__ attribute to feed the Content-Length header. | 258 defines a __len__ attribute to feed the Content-Length header. |
259 """ | 259 """ |
260 | 260 |
261 def __init__(self, *args, **kwargs): | 261 def __init__(self, ui, *args, **kwargs): |
262 # We can't just "self._data = open(*args, **kwargs)" here because there | 262 # We can't just "self._data = open(*args, **kwargs)" here because there |
263 # is an "open" function defined in this module that shadows the global | 263 # is an "open" function defined in this module that shadows the global |
264 # one | 264 # one |
265 self.ui = ui | |
265 self._data = __builtin__.open(*args, **kwargs) | 266 self._data = __builtin__.open(*args, **kwargs) |
266 self.read = self._data.read | |
267 self.seek = self._data.seek | 267 self.seek = self._data.seek |
268 self.close = self._data.close | 268 self.close = self._data.close |
269 self.write = self._data.write | 269 self.write = self._data.write |
270 self._len = os.fstat(self._data.fileno()).st_size | |
271 self._pos = 0 | |
272 self._total = len(self) / 1024 * 2 | |
273 | |
274 def read(self, *args, **kwargs): | |
275 try: | |
276 ret = self._data.read(*args, **kwargs) | |
277 except EOFError: | |
278 self.ui.progress(_('sending'), None) | |
279 self._pos += len(ret) | |
280 # We pass double the max for total because we currently have | |
281 # to send the bundle twice in the case of a server that | |
282 # requires authentication. Since we can't know until we try | |
283 # once whether authentication will be required, just lie to | |
284 # the user and maybe the push succeeds suddenly at 50%. | |
285 self.ui.progress(_('sending'), self._pos / 1024, | |
286 unit=_('kb'), total=self._total) | |
287 return ret | |
270 | 288 |
271 def __len__(self): | 289 def __len__(self): |
272 return os.fstat(self._data.fileno()).st_size | 290 return self._len |
273 | 291 |
274 def _gen_sendfile(connection): | 292 def _gen_sendfile(connection): |
275 def _sendfile(self, data): | 293 def _sendfile(self, data): |
276 # send a file | 294 # send a file |
277 if isinstance(data, httpsendfile): | 295 if isinstance(data, httpsendfile): |