Show More
@@ -140,12 +140,10 b' def peersetup(ui, peer):' | |||
|
140 | 140 | def getannotate(self, path, lastnode=None): |
|
141 | 141 | if not self.capable(b'getannotate'): |
|
142 | 142 | ui.warn(_(b'remote peer cannot provide annotate cache\n')) |
|
143 |
|
|
|
143 | return None, None | |
|
144 | 144 | else: |
|
145 | 145 | args = {b'path': path, b'lastnode': lastnode or b''} |
|
146 | f = wireprotov1peer.future() | |
|
147 | yield args, f | |
|
148 | yield _parseresponse(f.value) | |
|
146 | return args, _parseresponse | |
|
149 | 147 | |
|
150 | 148 | peer.__class__ = fastannotatepeer |
|
151 | 149 |
@@ -431,18 +431,19 b' def localrepolistkeys(orig, self, namesp' | |||
|
431 | 431 | @wireprotov1peer.batchable |
|
432 | 432 | def listkeyspatterns(self, namespace, patterns): |
|
433 | 433 | if not self.capable(b'pushkey'): |
|
434 |
|
|
|
435 | f = wireprotov1peer.future() | |
|
434 | return {}, None | |
|
436 | 435 | self.ui.debug(b'preparing listkeys for "%s"\n' % namespace) |
|
437 | yield { | |
|
438 | b'namespace': encoding.fromlocal(namespace), | |
|
439 | b'patterns': wireprototypes.encodelist(patterns), | |
|
440 | }, f | |
|
441 | d = f.value | |
|
436 | ||
|
437 | def decode(d): | |
|
442 | 438 | self.ui.debug( |
|
443 | 439 | b'received listkey for "%s": %i bytes\n' % (namespace, len(d)) |
|
444 | 440 | ) |
|
445 |
|
|
|
441 | return pushkey.decodekeys(d) | |
|
442 | ||
|
443 | return { | |
|
444 | b'namespace': encoding.fromlocal(namespace), | |
|
445 | b'patterns': wireprototypes.encodelist(patterns), | |
|
446 | }, decode | |
|
446 | 447 | |
|
447 | 448 | |
|
448 | 449 | def _readbundlerevs(bundlerepo): |
@@ -184,17 +184,18 b' def wirereposetup(ui, repo):' | |||
|
184 | 184 | |
|
185 | 185 | @wireprotov1peer.batchable |
|
186 | 186 | def statlfile(self, sha): |
|
187 | f = wireprotov1peer.future() | |
|
188 | result = {b'sha': sha} | |
|
189 | yield result, f | |
|
187 | def decode(d): | |
|
190 | 188 | try: |
|
191 |
|
|
|
189 | return int(d) | |
|
192 | 190 | except (ValueError, urlerr.httperror): |
|
193 | 191 | # If the server returns anything but an integer followed by a |
|
194 | 192 | # newline, newline, it's not speaking our language; if we get |
|
195 | 193 | # an HTTP error, we can't be sure the largefile is present; |
|
196 | 194 | # either way, consider it missing. |
|
197 |
|
|
|
195 | return 2 | |
|
196 | ||
|
197 | result = {b'sha': sha} | |
|
198 | return result, decode | |
|
198 | 199 | |
|
199 | 200 | repo.__class__ = lfileswirerepository |
|
200 | 201 |
@@ -63,12 +63,14 b' def peersetup(ui, peer):' | |||
|
63 | 63 | raise error.Abort( |
|
64 | 64 | b'configured remotefile server does not support getfile' |
|
65 | 65 | ) |
|
66 | f = wireprotov1peer.future() | |
|
67 | yield {b'file': file, b'node': node}, f | |
|
68 |
code, data = |
|
|
66 | ||
|
67 | def decode(d): | |
|
68 | code, data = d.split(b'\0', 1) | |
|
69 | 69 | if int(code): |
|
70 | 70 | raise error.LookupError(file, node, data) |
|
71 |
|
|
|
71 | return data | |
|
72 | ||
|
73 | return {b'file': file, b'node': node}, decode | |
|
72 | 74 | |
|
73 | 75 | @wireprotov1peer.batchable |
|
74 | 76 | def x_rfl_getflogheads(self, path): |
@@ -77,10 +79,11 b' def peersetup(ui, peer):' | |||
|
77 | 79 | b'configured remotefile server does not ' |
|
78 | 80 | b'support getflogheads' |
|
79 | 81 | ) |
|
80 | f = wireprotov1peer.future() | |
|
81 | yield {b'path': path}, f | |
|
82 |
|
|
|
83 | yield heads | |
|
82 | ||
|
83 | def decode(d): | |
|
84 | return d.split(b'\n') if d else [] | |
|
85 | ||
|
86 | return {b'path': path}, decode | |
|
84 | 87 | |
|
85 | 88 | def _updatecallstreamopts(self, command, opts): |
|
86 | 89 | if command != b'getbundle': |
@@ -35,7 +35,7 b' from .utils import hashutil' | |||
|
35 | 35 | urlreq = util.urlreq |
|
36 | 36 | |
|
37 | 37 | |
|
38 |
def batchable |
|
|
38 | def batchable(f): | |
|
39 | 39 | """annotation for batchable methods |
|
40 | 40 | |
|
41 | 41 | Such methods must implement a coroutine as follows: |
@@ -68,33 +68,6 b' def batchable_new_style(f):' | |||
|
68 | 68 | return plain |
|
69 | 69 | |
|
70 | 70 | |
|
71 | def batchable(f): | |
|
72 | def upgraded(*args, **opts): | |
|
73 | batchable = f(*args, **opts) | |
|
74 | encoded_args_or_res, encoded_res_future = next(batchable) | |
|
75 | if not encoded_res_future: | |
|
76 | decode = None | |
|
77 | else: | |
|
78 | ||
|
79 | def decode(d): | |
|
80 | encoded_res_future.set(d) | |
|
81 | return next(batchable) | |
|
82 | ||
|
83 | return encoded_args_or_res, decode | |
|
84 | ||
|
85 | setattr(upgraded, '__name__', f.__name__) | |
|
86 | return batchable_new_style(upgraded) | |
|
87 | ||
|
88 | ||
|
89 | class future(object): | |
|
90 | '''placeholder for a value to be set later''' | |
|
91 | ||
|
92 | def set(self, value): | |
|
93 | if util.safehasattr(self, b'value'): | |
|
94 | raise error.RepoError(b"future is already set") | |
|
95 | self.value = value | |
|
96 | ||
|
97 | ||
|
98 | 71 | def encodebatchcmds(req): |
|
99 | 72 | """Return a ``cmds`` argument value for the ``batch`` command.""" |
|
100 | 73 | escapearg = wireprototypes.escapebatcharg |
@@ -372,40 +345,39 b' class wirepeer(repository.peer):' | |||
|
372 | 345 | @batchable |
|
373 | 346 | def lookup(self, key): |
|
374 | 347 | self.requirecap(b'lookup', _(b'look up remote revision')) |
|
375 | f = future() | |
|
376 | yield {b'key': encoding.fromlocal(key)}, f | |
|
377 | d = f.value | |
|
348 | ||
|
349 | def decode(d): | |
|
378 | 350 | success, data = d[:-1].split(b" ", 1) |
|
379 | 351 | if int(success): |
|
380 |
|
|
|
352 | return bin(data) | |
|
381 | 353 | else: |
|
382 | 354 | self._abort(error.RepoError(data)) |
|
383 | 355 | |
|
356 | return {b'key': encoding.fromlocal(key)}, decode | |
|
357 | ||
|
384 | 358 | @batchable |
|
385 | 359 | def heads(self): |
|
386 |
f |
|
|
387 | yield {}, f | |
|
388 | d = f.value | |
|
360 | def decode(d): | |
|
389 | 361 | try: |
|
390 |
|
|
|
362 | return wireprototypes.decodelist(d[:-1]) | |
|
391 | 363 | except ValueError: |
|
392 | 364 | self._abort(error.ResponseError(_(b"unexpected response:"), d)) |
|
393 | 365 | |
|
366 | return {}, decode | |
|
367 | ||
|
394 | 368 | @batchable |
|
395 | 369 | def known(self, nodes): |
|
396 |
f |
|
|
397 | yield {b'nodes': wireprototypes.encodelist(nodes)}, f | |
|
398 | d = f.value | |
|
370 | def decode(d): | |
|
399 | 371 | try: |
|
400 |
|
|
|
372 | return [bool(int(b)) for b in pycompat.iterbytestr(d)] | |
|
401 | 373 | except ValueError: |
|
402 | 374 | self._abort(error.ResponseError(_(b"unexpected response:"), d)) |
|
403 | 375 | |
|
376 | return {b'nodes': wireprototypes.encodelist(nodes)}, decode | |
|
377 | ||
|
404 | 378 | @batchable |
|
405 | 379 | def branchmap(self): |
|
406 |
f |
|
|
407 | yield {}, f | |
|
408 | d = f.value | |
|
380 | def decode(d): | |
|
409 | 381 | try: |
|
410 | 382 | branchmap = {} |
|
411 | 383 | for branchpart in d.splitlines(): |
@@ -413,36 +385,33 b' class wirepeer(repository.peer):' | |||
|
413 | 385 | branchname = encoding.tolocal(urlreq.unquote(branchname)) |
|
414 | 386 | branchheads = wireprototypes.decodelist(branchheads) |
|
415 | 387 | branchmap[branchname] = branchheads |
|
416 |
|
|
|
388 | return branchmap | |
|
417 | 389 | except TypeError: |
|
418 | 390 | self._abort(error.ResponseError(_(b"unexpected response:"), d)) |
|
419 | 391 | |
|
392 | return {}, decode | |
|
393 | ||
|
420 | 394 | @batchable |
|
421 | 395 | def listkeys(self, namespace): |
|
422 | 396 | if not self.capable(b'pushkey'): |
|
423 |
|
|
|
424 | f = future() | |
|
397 | return {}, None | |
|
425 | 398 | self.ui.debug(b'preparing listkeys for "%s"\n' % namespace) |
|
426 | yield {b'namespace': encoding.fromlocal(namespace)}, f | |
|
427 | d = f.value | |
|
399 | ||
|
400 | def decode(d): | |
|
428 | 401 | self.ui.debug( |
|
429 | 402 | b'received listkey for "%s": %i bytes\n' % (namespace, len(d)) |
|
430 | 403 | ) |
|
431 |
|
|
|
404 | return pushkeymod.decodekeys(d) | |
|
405 | ||
|
406 | return {b'namespace': encoding.fromlocal(namespace)}, decode | |
|
432 | 407 | |
|
433 | 408 | @batchable |
|
434 | 409 | def pushkey(self, namespace, key, old, new): |
|
435 | 410 | if not self.capable(b'pushkey'): |
|
436 |
|
|
|
437 | f = future() | |
|
411 | return False, None | |
|
438 | 412 | self.ui.debug(b'preparing pushkey for "%s:%s"\n' % (namespace, key)) |
|
439 | yield { | |
|
440 | b'namespace': encoding.fromlocal(namespace), | |
|
441 | b'key': encoding.fromlocal(key), | |
|
442 | b'old': encoding.fromlocal(old), | |
|
443 | b'new': encoding.fromlocal(new), | |
|
444 | }, f | |
|
445 | d = f.value | |
|
413 | ||
|
414 | def decode(d): | |
|
446 | 415 | d, output = d.split(b'\n', 1) |
|
447 | 416 | try: |
|
448 | 417 | d = bool(int(d)) |
@@ -452,7 +421,14 b' class wirepeer(repository.peer):' | |||
|
452 | 421 | ) |
|
453 | 422 | for l in output.splitlines(True): |
|
454 | 423 | self.ui.status(_(b'remote: '), l) |
|
455 |
|
|
|
424 | return d | |
|
425 | ||
|
426 | return { | |
|
427 | b'namespace': encoding.fromlocal(namespace), | |
|
428 | b'key': encoding.fromlocal(key), | |
|
429 | b'old': encoding.fromlocal(old), | |
|
430 | b'new': encoding.fromlocal(new), | |
|
431 | }, decode | |
|
456 | 432 | |
|
457 | 433 | def stream_out(self): |
|
458 | 434 | return self._callstream(b'stream_out') |
@@ -214,14 +214,11 b' class remotething(thing):' | |||
|
214 | 214 | mangle(two), |
|
215 | 215 | ), |
|
216 | 216 | ] |
|
217 | encoded_res_future = wireprotov1peer.future() | |
|
218 | yield encoded_args, encoded_res_future | |
|
219 | yield unmangle(encoded_res_future.value) | |
|
217 | return encoded_args, unmangle | |
|
220 | 218 | |
|
221 | 219 | @wireprotov1peer.batchable |
|
222 | 220 | def bar(self, b, a): |
|
223 | encresref = wireprotov1peer.future() | |
|
224 | yield [ | |
|
221 | return [ | |
|
225 | 222 | ( |
|
226 | 223 | b'b', |
|
227 | 224 | mangle(b), |
@@ -230,8 +227,7 b' class remotething(thing):' | |||
|
230 | 227 | b'a', |
|
231 | 228 | mangle(a), |
|
232 | 229 | ), |
|
233 |
], |
|
|
234 | yield unmangle(encresref.value) | |
|
230 | ], unmangle | |
|
235 | 231 | |
|
236 | 232 | # greet is coded directly. It therefore does not support batching. If it |
|
237 | 233 | # does appear in a batch, the batch is split around greet, and the call to |
@@ -75,9 +75,7 b' class clientpeer(wireprotov1peer.wirepee' | |||
|
75 | 75 | |
|
76 | 76 | @wireprotov1peer.batchable |
|
77 | 77 | def greet(self, name): |
|
78 | f = wireprotov1peer.future() | |
|
79 | yield {b'name': mangle(name)}, f | |
|
80 | yield unmangle(f.value) | |
|
78 | return {b'name': mangle(name)}, unmangle | |
|
81 | 79 | |
|
82 | 80 | |
|
83 | 81 | class serverrepo(object): |
General Comments 0
You need to be logged in to leave comments.
Login now