Mercurial > hg
annotate mercurial/wireprotov2peer.py @ 42044:bb271ec2fbfb
compression: introduce a `storage.revlog.zstd.level` configuration
This option control the zstd compression level used when compressing revlog
chunk. The usage of zstd for revlog compression has not graduated from
experimental yet, but we intend to fix that soon.
The option name for the compression level is more straight forward to pick, so
this changesets comes first. Having a dedicated option for each compression
engine is useful because they don't support the same range of values.
I ran the same measurement as for the zlib compression level (in the parent
changesets). The variation in repository size is stay mostly in the same (small)
range. The "read/write" performance see smallish variation, but are overall much
better than zlib. Write performance show the same tend of having better write
performance for when reaching high-end compression.
Again, we don't intend to change the default zstd compression level (currently:
3) in this series. However this is worth investigating in the future.
The Performance comparison of zlib vs zstd is quite impressive. The repository
size stay in the same range, but the performance are much better in all
situations.
Comparison summary
==================
We are looking at:
- performance range for zlib
- performance range for zstd
- comparison of default zstd (level-3) to default zlib (level 6)
- comparison of the slowest zstd time to the fastest zlib time
Read performance:
-----------------
| zlib | zstd | cmp | f2s
mercurial | 0.170159 - 0.189219 | 0.144127 - 0.149624 | 80% | 88%
pypy | 2.679217 - 2.768691 | 1.532317 - 1.705044 | 60% | 63%
netbeans | 122.477027 - 141.620281 | 72.996346 - 89.731560 | 58% | 73%
mozilla | 147.867662 - 170.572118 | 91.700995 - 105.853099 | 56% | 71%
Write performance:
------------------
| zlib | zstd | cmp | f2s
mercurial | 53.250304 - 56.2936129 | 40.877025 - 45.677286 | 75% | 86%
pypy | 460.721984 - 476.589918 | 270.545409 - 301.002219 | 63% | 65%
netbeans | 520.560316 - 715.930400 | 370.356311 - 428.329652 | 55% | 82%
mozilla | 739.803002 - 987.056093 | 505.152906 - 591.930683 | 57% | 80%
Raw data
--------
repo alg lvl .hg/store size 00manifest.d read write
mercurial zlib 1 49,402,813 5,963,475 0.170159 53.250304
mercurial zlib 6 47,197,397 5,875,730 0.182820 56.264320
mercurial zlib 9 47,121,596 5,849,781 0.189219 56.293612
mercurial zstd 1 49,737,084 5,966,355 0.144127 40.877025
mercurial zstd 3 48,961,867 5,895,208 0.146376 42.268142
mercurial zstd 5 48,200,592 5,938,676 0.149624 43.162875
mercurial zstd 10 47,833,520 5,913,353 0.145185 44.012489
mercurial zstd 15 47,314,604 5,728,679 0.147686 45.677286
mercurial zstd 20 47,330,502 5,830,539 0.145789 45.025407
mercurial zstd 22 47,330,076 5,830,539 0.143996 44.690460
pypy zlib 1 370,830,572 28,462,425 2.679217 460.721984
pypy zlib 6 340,112,317 27,648,747 2.768691 467.537158
pypy zlib 9 338,360,736 27,639,003 2.763495 476.589918
pypy zstd 1 362,377,479 27,916,214 1.532317 270.545409
pypy zstd 3 354,137,693 27,905,988 1.686718 294.951509
pypy zstd 5 342,640,043 27,655,774 1.705044 301.002219
pypy zstd 10 334,224,327 27,164,493 1.567287 285.186239
pypy zstd 15 329,000,363 26,645,965 1.637729 299.561332
pypy zstd 20 324,534,039 26,199,547 1.526813 302.149827
pypy zstd 22 324,530,595 26,198,932 1.525718 307.821218
netbeans zlib 1 1,281,847,810 165,495,457 122.477027 520.560316
netbeans zlib 6 1,205,284,353 159,161,207 139.876147 715.930400
netbeans zlib 9 1,197,135,671 155,034,586 141.620281 678.297064
netbeans zstd 1 1,259,581,737 160,840,613 72.996346 370.356311
netbeans zstd 3 1,232,978,122 157,691,551 81.622317 396.733087
netbeans zstd 5 1,208,034,075 160,246,880 83.080549 364.342626
netbeans zstd 10 1,188,624,176 156,083,417 79.323935 403.594602
netbeans zstd 15 1,176,973,589 153,859,477 89.731560 428.329652
netbeans zstd 20 1,162,958,258 151,147,535 82.842667 392.335349
netbeans zstd 22 1,162,707,029 151,150,220 82.565695 402.840655
mozilla zlib 1 2,775,497,186 298,527,987 147.867662 751.263721
mozilla zlib 6 2,596,856,420 286,597,671 170.572118 987.056093
mozilla zlib 9 2,587,542,494 287,018,264 163.622338 739.803002
mozilla zstd 1 2,723,159,348 286,617,532 91.700995 570.042751
mozilla zstd 3 2,665,055,001 286,152,013 95.240155 561.412805
mozilla zstd 5 2,607,819,817 288,060,030 101.978048 505.152906
mozilla zstd 10 2,558,761,085 283,967,648 104.113481 497.771202
mozilla zstd 15 2,526,216,060 275,581,300 105.853099 591.930683
mozilla zstd 20 2,485,114,806 266,478,859 95.268795 576.515389
mozilla zstd 22 2,484,869,080 266,456,505 94.429282 572.785537
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 27 Mar 2019 18:35:59 +0100 |
parents | 090a797f2b47 |
children | 2372284d9457 |
rev | line source |
---|---|
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
1 # wireprotov2peer.py - client side code for wire protocol version 2 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
2 # |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
4 # |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
7 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
8 from __future__ import absolute_import |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
9 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
10 import threading |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
11 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
12 from .i18n import _ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
13 from . import ( |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
14 encoding, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 error, |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
16 pycompat, |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
17 sslutil, |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
18 url as urlmod, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
19 util, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 wireprotoframing, |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
21 wireprototypes, |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
22 ) |
39450
9f51fd22ed50
wireprotov2peer: use our CBOR decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39438
diff
changeset
|
23 from .utils import ( |
9f51fd22ed50
wireprotov2peer: use our CBOR decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39438
diff
changeset
|
24 cborutil, |
9f51fd22ed50
wireprotov2peer: use our CBOR decoder
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39438
diff
changeset
|
25 ) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
27 def formatrichmessage(atoms): |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
28 """Format an encoded message from the framing protocol.""" |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
29 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
30 chunks = [] |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
31 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
32 for atom in atoms: |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
33 msg = _(atom[b'msg']) |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
34 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
35 if b'args' in atom: |
39486
43d92d68ac88
wireprotov2peer: properly format errors
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39485
diff
changeset
|
36 msg = msg % tuple(atom[b'args']) |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
37 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
38 chunks.append(msg) |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
39 |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
40 return b''.join(chunks) |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
41 |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
42 SUPPORTED_REDIRECT_PROTOCOLS = { |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
43 b'http', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
44 b'https', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
45 } |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
46 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
47 SUPPORTED_CONTENT_HASHES = { |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
48 b'sha1', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
49 b'sha256', |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
50 } |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
51 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
52 def redirecttargetsupported(ui, target): |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
53 """Determine whether a redirect target entry is supported. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
54 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
55 ``target`` should come from the capabilities data structure emitted by |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
56 the server. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
57 """ |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
58 if target.get(b'protocol') not in SUPPORTED_REDIRECT_PROTOCOLS: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
59 ui.note(_('(remote redirect target %s uses unsupported protocol: %s)\n') |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
60 % (target[b'name'], target.get(b'protocol', b''))) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
61 return False |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
62 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
63 if target.get(b'snirequired') and not sslutil.hassni: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
64 ui.note(_('(redirect target %s requires SNI, which is unsupported)\n') % |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
65 target[b'name']) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
66 return False |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
67 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
68 if b'tlsversions' in target: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
69 tlsversions = set(target[b'tlsversions']) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
70 supported = set() |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
71 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
72 for v in sslutil.supportedprotocols: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
73 assert v.startswith(b'tls') |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
74 supported.add(v[3:]) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
75 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
76 if not tlsversions & supported: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
77 ui.note(_('(remote redirect target %s requires unsupported TLS ' |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
78 'versions: %s)\n') % ( |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
79 target[b'name'], b', '.join(sorted(tlsversions)))) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
80 return False |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
81 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
82 ui.note(_('(remote redirect target %s is compatible)\n') % target[b'name']) |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
83 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
84 return True |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
85 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
86 def supportedredirects(ui, apidescriptor): |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
87 """Resolve the "redirect" command request key given an API descriptor. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
88 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
89 Given an API descriptor returned by the server, returns a data structure |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
90 that can be used in hte "redirect" field of command requests to advertise |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
91 support for compatible redirect targets. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
92 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
93 Returns None if no redirect targets are remotely advertised or if none are |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
94 supported. |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
95 """ |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
96 if not apidescriptor or b'redirect' not in apidescriptor: |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
97 return None |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
98 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
99 targets = [t[b'name'] for t in apidescriptor[b'redirect'][b'targets'] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
100 if redirecttargetsupported(ui, t)] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
101 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
102 hashes = [h for h in apidescriptor[b'redirect'][b'hashes'] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
103 if h in SUPPORTED_CONTENT_HASHES] |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
104 |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
105 return { |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
106 b'targets': targets, |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
107 b'hashes': hashes, |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
108 } |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
109 |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
110 class commandresponse(object): |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
111 """Represents the response to a command request. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
112 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
113 Instances track the state of the command and hold its results. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
114 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
115 An external entity is required to update the state of the object when |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
116 events occur. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
117 """ |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
118 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
119 def __init__(self, requestid, command, fromredirect=False): |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
120 self.requestid = requestid |
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
121 self.command = command |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
122 self.fromredirect = fromredirect |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
123 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
124 # Whether all remote input related to this command has been |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
125 # received. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
126 self._inputcomplete = False |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
127 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
128 # We have a lock that is acquired when important object state is |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
129 # mutated. This is to prevent race conditions between 1 thread |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
130 # sending us new data and another consuming it. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
131 self._lock = threading.RLock() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
132 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
133 # An event is set when state of the object changes. This event |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
134 # is waited on by the generator emitting objects. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
135 self._serviceable = threading.Event() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
136 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
137 self._pendingevents = [] |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
138 self._pendingerror = None |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
139 self._decoder = cborutil.bufferingdecoder() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
140 self._seeninitial = False |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
141 self._redirect = None |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
142 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
143 def _oninputcomplete(self): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
144 with self._lock: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
145 self._inputcomplete = True |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
146 self._serviceable.set() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
147 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
148 def _onresponsedata(self, data): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
149 available, readcount, wanted = self._decoder.decode(data) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
150 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
151 if not available: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
152 return |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
153 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
154 with self._lock: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
155 for o in self._decoder.getavailable(): |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
156 if not self._seeninitial and not self.fromredirect: |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
157 self._handleinitial(o) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
158 continue |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
159 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
160 # We should never see an object after a content redirect, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
161 # as the spec says the main status object containing the |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
162 # content redirect is the only object in the stream. Fail |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
163 # if we see a misbehaving server. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
164 if self._redirect: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
165 raise error.Abort(_('received unexpected response data ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
166 'after content redirect; the remote is ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
167 'buggy')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
168 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
169 self._pendingevents.append(o) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
170 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
171 self._serviceable.set() |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
172 |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
173 def _onerror(self, e): |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
174 self._pendingerror = e |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
175 |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
176 with self._lock: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
177 self._serviceable.set() |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
178 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
179 def _handleinitial(self, o): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
180 self._seeninitial = True |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
181 if o[b'status'] == b'ok': |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
182 return |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
183 |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
184 elif o[b'status'] == b'redirect': |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
185 l = o[b'location'] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
186 self._redirect = wireprototypes.alternatelocationresponse( |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
187 url=l[b'url'], |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
188 mediatype=l[b'mediatype'], |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
189 size=l.get(b'size'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
190 fullhashes=l.get(b'fullhashes'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
191 fullhashseed=l.get(b'fullhashseed'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
192 serverdercerts=l.get(b'serverdercerts'), |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
193 servercadercerts=l.get(b'servercadercerts')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
194 return |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
195 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
196 atoms = [{'msg': o[b'error'][b'message']}] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
197 if b'args' in o[b'error']: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
198 atoms[0]['args'] = o[b'error'][b'args'] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
199 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
200 raise error.RepoError(formatrichmessage(atoms)) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
201 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
202 def objects(self): |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
203 """Obtained decoded objects from this response. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
204 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
205 This is a generator of data structures that were decoded from the |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
206 command response. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
207 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
208 Obtaining the next member of the generator may block due to waiting |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
209 on external data to become available. |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
210 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
211 If the server encountered an error in the middle of serving the data |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
212 or if another error occurred, an exception may be raised when |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
213 advancing the generator. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
214 """ |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
215 while True: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
216 # TODO this can infinite loop if self._inputcomplete is never |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
217 # set. We likely want to tie the lifetime of this object/state |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
218 # to that of the background thread receiving frames and updating |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
219 # our state. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
220 self._serviceable.wait(1.0) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
221 |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
222 if self._pendingerror: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
223 raise self._pendingerror |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
224 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
225 with self._lock: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
226 self._serviceable.clear() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
227 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
228 # Make copies because objects could be mutated during |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
229 # iteration. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
230 stop = self._inputcomplete |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
231 pending = list(self._pendingevents) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
232 self._pendingevents[:] = [] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
233 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
234 for o in pending: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
235 yield o |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
236 |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
237 if stop: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
238 break |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
239 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
240 class clienthandler(object): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
241 """Object to handle higher-level client activities. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
242 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
243 The ``clientreactor`` is used to hold low-level state about the frame-based |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
244 protocol, such as which requests and streams are active. This type is used |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
245 for higher-level operations, such as reading frames from a socket, exposing |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
246 and managing a higher-level primitive for representing command responses, |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
247 etc. This class is what peers should probably use to bridge wire activity |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
248 with the higher-level peer API. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
249 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
250 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
251 def __init__(self, ui, clientreactor, opener=None, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
252 requestbuilder=util.urlreq.request): |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
253 self._ui = ui |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
254 self._reactor = clientreactor |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
255 self._requests = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
256 self._futures = {} |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
257 self._responses = {} |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
258 self._redirects = [] |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
259 self._frameseof = False |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
260 self._opener = opener or urlmod.opener(ui) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
261 self._requestbuilder = requestbuilder |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
262 |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
263 def callcommand(self, command, args, f, redirect=None): |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
264 """Register a request to call a command. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
265 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
266 Returns an iterable of frames that should be sent over the wire. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
267 """ |
40024
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
268 request, action, meta = self._reactor.callcommand(command, args, |
86b22a4cfab1
wireprotov2: client support for advertising redirect targets
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40019
diff
changeset
|
269 redirect=redirect) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
270 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
271 if action != 'noop': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
272 raise error.ProgrammingError('%s not yet supported' % action) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
273 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
274 rid = request.requestid |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
275 self._requests[rid] = request |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
276 self._futures[rid] = f |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
277 # TODO we need some kind of lifetime on response instances otherwise |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
278 # objects() may deadlock. |
37720
d715a85003c8
wireprotov2: establish a type for representing command response
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37719
diff
changeset
|
279 self._responses[rid] = commandresponse(rid, command) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
280 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
281 return iter(()) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
282 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
283 def flushcommands(self): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
284 """Flush all queued commands. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
285 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
286 Returns an iterable of frames that should be sent over the wire. |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
287 """ |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
288 action, meta = self._reactor.flushcommands() |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
289 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
290 if action != 'sendframes': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
291 raise error.ProgrammingError('%s not yet supported' % action) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
292 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
293 return meta['framegen'] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
294 |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
295 def readdata(self, framefh): |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
296 """Attempt to read data and do work. |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
297 |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
298 Returns None if no data was read. Presumably this means we're |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
299 done with all read I/O. |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
300 """ |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
301 if not self._frameseof: |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
302 frame = wireprotoframing.readframe(framefh) |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
303 if frame is None: |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
304 # TODO tell reactor? |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
305 self._frameseof = True |
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
306 else: |
41380
090a797f2b47
wireprotov2peer: make "received frame(...)" messages debug level
Gregory Szorc <gregory.szorc@gmail.com>
parents:
41378
diff
changeset
|
307 self._ui.debug('received %r\n' % frame) |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
308 self._processframe(frame) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
309 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
310 # Also try to read the first redirect. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
311 if self._redirects: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
312 if not self._processredirect(*self._redirects[0]): |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
313 self._redirects.pop(0) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
314 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
315 if self._frameseof and not self._redirects: |
40019
f5a05bb48116
wireprotov2: change name and behavior of readframe()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39561
diff
changeset
|
316 return None |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
317 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
318 return True |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
319 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
320 def _processframe(self, frame): |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
321 """Process a single read frame.""" |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
322 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
323 action, meta = self._reactor.onframerecv(frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
324 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
325 if action == 'error': |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
326 e = error.RepoError(meta['message']) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
327 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
328 if frame.requestid in self._responses: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
329 self._responses[frame.requestid]._oninputcomplete() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
330 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
331 if frame.requestid in self._futures: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
332 self._futures[frame.requestid].set_exception(e) |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
333 del self._futures[frame.requestid] |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
334 else: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
335 raise e |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
336 |
39559
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39486
diff
changeset
|
337 return |
40134
cfeba1aafb9d
wireprotov2: handle noop action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40026
diff
changeset
|
338 elif action == 'noop': |
cfeba1aafb9d
wireprotov2: handle noop action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40026
diff
changeset
|
339 return |
40139
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
340 elif action == 'responsedata': |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
341 # Handled below. |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
342 pass |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
343 else: |
17223d8e7d75
wireprotov2: raise ProgrammingError on unknown action
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40137
diff
changeset
|
344 raise error.ProgrammingError('action not handled: %s' % action) |
39559
07b58266bce3
wireprotov2: implement commands as a generator of objects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39486
diff
changeset
|
345 |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
346 if frame.requestid not in self._requests: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
347 raise error.ProgrammingError( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
348 'received frame for unknown request; this is either a bug in ' |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
349 'the clientreactor not screening for this or this instance was ' |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
350 'never told about this request: %r' % frame) |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
351 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
352 response = self._responses[frame.requestid] |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
353 |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
354 if action == 'responsedata': |
39485
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
355 # Any failures processing this frame should bubble up to the |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
356 # future tracking the request. |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
357 try: |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
358 self._processresponsedata(frame, meta, response) |
42bc1c70a6b8
wireprotov2peer: report exceptions in frame handling against request future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39450
diff
changeset
|
359 except BaseException as e: |
40137
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
360 # If an exception occurs before the future is resolved, |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
361 # fail the future. Otherwise, we stuff the exception on |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
362 # the response object so it can be raised during objects() |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
363 # iteration. If nothing is consuming objects(), we could |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
364 # silently swallow this exception. That's a risk we'll have to |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
365 # take. |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
366 if frame.requestid in self._futures: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
367 self._futures[frame.requestid].set_exception(e) |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
368 del self._futures[frame.requestid] |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
369 response._oninputcomplete() |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
370 else: |
ed4ebbb98ca0
wireprotov2: raise exception in objects() if future has been resolved
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40134
diff
changeset
|
371 response._onerror(e) |
37719
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
372 else: |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
373 raise error.ProgrammingError( |
a656cba08a04
wireprotov2: move response handling out of httppeer
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
374 'unhandled action from clientreactor: %s' % action) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
375 |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
376 def _processresponsedata(self, frame, meta, response): |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
377 # This can raise. The caller can handle it. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
378 response._onresponsedata(meta['data']) |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
379 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
380 # We need to be careful about resolving futures prematurely. If a |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
381 # response is a redirect response, resolving the future before the |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
382 # redirect is processed would result in the consumer seeing an |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
383 # empty stream of objects, since they'd be consuming our |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
384 # response.objects() instead of the redirect's response.objects(). |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
385 # |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
386 # Our strategy is to not resolve/finish the request until either |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
387 # EOS occurs or until the initial response object is fully received. |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
388 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
389 # Always react to eos. |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
390 if meta['eos']: |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
391 response._oninputcomplete() |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
392 del self._requests[frame.requestid] |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
393 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
394 # Not EOS but we haven't decoded the initial response object yet. |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
395 # Return and wait for more data. |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
396 elif not response._seeninitial: |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
397 return |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
398 |
40724
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
399 # The specification says no objects should follow the initial/redirect |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
400 # object. So it should be safe to handle the redirect object if one is |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
401 # decoded, without having to wait for EOS. |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
402 if response._redirect: |
15a643304728
wireprotov2peer: wait for initial object before resolving future
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40723
diff
changeset
|
403 self._followredirect(frame.requestid, response._redirect) |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
404 return |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
405 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
406 # If the command has a decoder, we wait until all input has been |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
407 # received before resolving the future. Otherwise we resolve the |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
408 # future immediately. |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
409 if frame.requestid not in self._futures: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
410 return |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
411 |
39561
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
412 if response.command not in COMMAND_DECODERS: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
413 self._futures[frame.requestid].set_result(response.objects()) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
414 del self._futures[frame.requestid] |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
415 elif response._inputcomplete: |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
416 decoded = COMMAND_DECODERS[response.command](response.objects()) |
d06834e0f48e
wireprotov2peer: stream decoded responses
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39559
diff
changeset
|
417 self._futures[frame.requestid].set_result(decoded) |
39438
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
418 del self._futures[frame.requestid] |
c734a5c82f38
wireprotov2peer: split responsedata handling into separate function
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39435
diff
changeset
|
419 |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
420 def _followredirect(self, requestid, redirect): |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
421 """Called to initiate redirect following for a request.""" |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
422 self._ui.note(_('(following redirect to %s)\n') % redirect.url) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
423 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
424 # TODO handle framed responses. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
425 if redirect.mediatype != b'application/mercurial-cbor': |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
426 raise error.Abort(_('cannot handle redirects for the %s media type') |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
427 % redirect.mediatype) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
428 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
429 if redirect.fullhashes: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
430 self._ui.warn(_('(support for validating hashes on content ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
431 'redirects not supported)\n')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
432 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
433 if redirect.serverdercerts or redirect.servercadercerts: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
434 self._ui.warn(_('(support for pinning server certificates on ' |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
435 'content redirects not supported)\n')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
436 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
437 headers = { |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
438 r'Accept': redirect.mediatype, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
439 } |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
440 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
441 req = self._requestbuilder(pycompat.strurl(redirect.url), None, headers) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
442 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
443 try: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
444 res = self._opener.open(req) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
445 except util.urlerr.httperror as e: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
446 if e.code == 401: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
447 raise error.Abort(_('authorization failed')) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
448 raise |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
449 except util.httplib.HTTPException as e: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
450 self._ui.debug('http error requesting %s\n' % req.get_full_url()) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
451 self._ui.traceback() |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
452 raise IOError(None, e) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
453 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
454 urlmod.wrapresponse(res) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
455 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
456 # The existing response object is associated with frame data. Rather |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
457 # than try to normalize its state, just create a new object. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
458 oldresponse = self._responses[requestid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
459 self._responses[requestid] = commandresponse(requestid, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
460 oldresponse.command, |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
461 fromredirect=True) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
462 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
463 self._redirects.append((requestid, res)) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
464 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
465 def _processredirect(self, rid, res): |
40723
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
466 """Called to continue processing a response from a redirect. |
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
467 |
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
468 Returns a bool indicating if the redirect is still serviceable. |
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
469 """ |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
470 response = self._responses[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
471 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
472 try: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
473 data = res.read(32768) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
474 response._onresponsedata(data) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
475 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
476 # We're at end of stream. |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
477 if not data: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
478 response._oninputcomplete() |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
479 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
480 if rid not in self._futures: |
40723
94b0d0f996e1
wireprotov2peer: always return a bool from _processredirect()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40139
diff
changeset
|
481 return bool(data) |
40026
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
482 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
483 if response.command not in COMMAND_DECODERS: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
484 self._futures[rid].set_result(response.objects()) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
485 del self._futures[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
486 elif response._inputcomplete: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
487 decoded = COMMAND_DECODERS[response.command](response.objects()) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
488 self._futures[rid].set_result(decoded) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
489 del self._futures[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
490 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
491 return bool(data) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
492 |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
493 except BaseException as e: |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
494 self._futures[rid].set_exception(e) |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
495 del self._futures[rid] |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
496 response._oninputcomplete() |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
497 return False |
7e807b8a9e56
wireprotov2: client support for following content redirects
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40024
diff
changeset
|
498 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
499 def decodebranchmap(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
500 # Response should be a single CBOR map of branch name to array of nodes. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
501 bm = next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
502 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
503 return {encoding.tolocal(k): v for k, v in bm.items()} |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
504 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
505 def decodeheads(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
506 # Array of node bytestrings. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
507 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
508 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
509 def decodeknown(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
510 # Bytestring where each byte is a 0 or 1. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
511 raw = next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
512 |
41378
e6c1c6478d04
wireprotov2peer: rewrite character traversal to use slices
Gregory Szorc <gregory.szorc@gmail.com>
parents:
40724
diff
changeset
|
513 return [True if raw[i:i + 1] == b'1' else False for i in range(len(raw))] |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
514 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
515 def decodelistkeys(objs): |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
516 # Map with bytestring keys and values. |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
517 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
518 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
519 def decodelookup(objs): |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
520 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
521 |
37725
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
522 def decodepushkey(objs): |
3ea8323d6f95
wireprotov2: change command response protocol to include a leading map
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37722
diff
changeset
|
523 return next(objs) |
37721
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
524 |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
525 COMMAND_DECODERS = { |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
526 'branchmap': decodebranchmap, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
527 'heads': decodeheads, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
528 'known': decodeknown, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
529 'listkeys': decodelistkeys, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
530 'lookup': decodelookup, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
531 'pushkey': decodepushkey, |
f7673845b167
wireprotov2: decode responses to their expected types
Gregory Szorc <gregory.szorc@gmail.com>
parents:
37720
diff
changeset
|
532 } |