Mercurial > public > mercurial-scm > hg
comparison mercurial/wireprotoserver.py @ 37414:2d965bfeb8f6
wireproto: allow direct stream processing for unbundle
Introduce a new option server.streamunbundle which starts a transaction
immediately to apply a bundle instead of writing it to a temporary file
first. This side steps the need for a large tmp directory at the cost of
preventing concurrent pushes. This is a reasonable trade-off for many
setups as concurrent pushes for the main branch at least are disallowed
anyway. The option defaults to off to preserve existing behavior.
Change the wireproto interface to provide a generator for reading the
payload and make callers responsible for consuming all data.
Differential Revision: https://phab.mercurial-scm.org/D2470
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Tue, 27 Feb 2018 02:37:31 +0100 |
parents | afcfdf53e4b5 |
children | 0b7475ea38cf |
comparison
equal
deleted
inserted
replaced
37413:33af46d639b4 | 37414:2d965bfeb8f6 |
---|---|
104 if self._protocaps is None: | 104 if self._protocaps is None: |
105 value = decodevaluefromheaders(self._req, r'X-HgProto') | 105 value = decodevaluefromheaders(self._req, r'X-HgProto') |
106 self._protocaps = set(value.split(' ')) | 106 self._protocaps = set(value.split(' ')) |
107 return self._protocaps | 107 return self._protocaps |
108 | 108 |
109 def forwardpayload(self, fp): | 109 def getpayload(self): |
110 # Existing clients *always* send Content-Length. | 110 # Existing clients *always* send Content-Length. |
111 length = int(self._req.headers[b'Content-Length']) | 111 length = int(self._req.headers[b'Content-Length']) |
112 | 112 |
113 # If httppostargs is used, we need to read Content-Length | 113 # If httppostargs is used, we need to read Content-Length |
114 # minus the amount that was consumed by args. | 114 # minus the amount that was consumed by args. |
115 length -= int(self._req.headers.get(b'X-HgArgs-Post', 0)) | 115 length -= int(self._req.headers.get(b'X-HgArgs-Post', 0)) |
116 for s in util.filechunkiter(self._req.bodyfh, limit=length): | 116 return util.filechunkiter(self._req.bodyfh, limit=length) |
117 fp.write(s) | |
118 | 117 |
119 @contextlib.contextmanager | 118 @contextlib.contextmanager |
120 def mayberedirectstdio(self): | 119 def mayberedirectstdio(self): |
121 oldout = self._ui.fout | 120 oldout = self._ui.fout |
122 olderr = self._ui.ferr | 121 olderr = self._ui.ferr |
608 | 607 |
609 def getprotocaps(self): | 608 def getprotocaps(self): |
610 # Protocol capabilities are currently not implemented for HTTP V2. | 609 # Protocol capabilities are currently not implemented for HTTP V2. |
611 return set() | 610 return set() |
612 | 611 |
613 def forwardpayload(self, fp): | 612 def getpayload(self): |
614 raise NotImplementedError | 613 raise NotImplementedError |
615 | 614 |
616 @contextlib.contextmanager | 615 @contextlib.contextmanager |
617 def mayberedirectstdio(self): | 616 def mayberedirectstdio(self): |
618 raise NotImplementedError | 617 raise NotImplementedError |
781 return [data[k] for k in keys] | 780 return [data[k] for k in keys] |
782 | 781 |
783 def getprotocaps(self): | 782 def getprotocaps(self): |
784 return self._protocaps | 783 return self._protocaps |
785 | 784 |
786 def forwardpayload(self, fpout): | 785 def getpayload(self): |
787 # We initially send an empty response. This tells the client it is | 786 # We initially send an empty response. This tells the client it is |
788 # OK to start sending data. If a client sees any other response, it | 787 # OK to start sending data. If a client sees any other response, it |
789 # interprets it as an error. | 788 # interprets it as an error. |
790 _sshv1respondbytes(self._fout, b'') | 789 _sshv1respondbytes(self._fout, b'') |
791 | 790 |
794 # <chunk size>\n<chunk> | 793 # <chunk size>\n<chunk> |
795 # ... | 794 # ... |
796 # 0\n | 795 # 0\n |
797 count = int(self._fin.readline()) | 796 count = int(self._fin.readline()) |
798 while count: | 797 while count: |
799 fpout.write(self._fin.read(count)) | 798 yield self._fin.read(count) |
800 count = int(self._fin.readline()) | 799 count = int(self._fin.readline()) |
801 | 800 |
802 @contextlib.contextmanager | 801 @contextlib.contextmanager |
803 def mayberedirectstdio(self): | 802 def mayberedirectstdio(self): |
804 yield None | 803 yield None |