comparison mercurial/wireprotoserver.py @ 37485:0b7475ea38cf

wireproto: port heads command to wire protocol v2 After much thought and consideration, wire protocol version 2's commands will be defined in different functions from the existing commands. This will make it easier to implement these commands because it won't require shoehorning things like response formatting and argument declaration into the same APIs. For example, wire protocol version 1 requires that commands declare a fixed and ordered list of argument names. It isn't really possible to insert new arguments or have optional arguments without breaking backwards compatibility. Wire protocol version 2, however, uses CBOR maps for passing arguments. So arguments a) can be optional b) can be added without BC c) can be strongly typed. This commit starts our trek towards reimplementing the wire protocol for version 2 with the heads command. It is pretty similar to the existing heads command. One added feature is it can be told to operate on only public phase changesets. This is useful for making discovery faster when a repo has tens of thousands of draft phase heads (such as Mozilla's "try" repository). The HTTPv2 server-side protocol has had its `getargs()` implementation updated to reflect that arguments are a map and not a list. Differential Revision: https://phab.mercurial-scm.org/D3179
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 28 Mar 2018 14:55:13 -0700
parents 2d965bfeb8f6
children df4985497986
comparison
equal deleted inserted replaced
37484:c22fd3c4c23e 37485:0b7475ea38cf
10 import struct 10 import struct
11 import sys 11 import sys
12 import threading 12 import threading
13 13
14 from .i18n import _ 14 from .i18n import _
15 from .thirdparty import (
16 cbor,
17 )
15 from .thirdparty.zope import ( 18 from .thirdparty.zope import (
16 interface as zi, 19 interface as zi,
17 ) 20 )
18 from . import ( 21 from . import (
19 encoding, 22 encoding,
561 564
562 if isinstance(rsp, wireprototypes.bytesresponse): 565 if isinstance(rsp, wireprototypes.bytesresponse):
563 action, meta = reactor.onbytesresponseready(outstream, 566 action, meta = reactor.onbytesresponseready(outstream,
564 command['requestid'], 567 command['requestid'],
565 rsp.data) 568 rsp.data)
569 elif isinstance(rsp, wireprototypes.cborresponse):
570 encoded = cbor.dumps(rsp.value, canonical=True)
571 action, meta = reactor.onbytesresponseready(outstream,
572 command['requestid'],
573 encoded,
574 iscbor=True)
566 else: 575 else:
567 action, meta = reactor.onapplicationerror( 576 action, meta = reactor.onapplicationerror(
568 _('unhandled response type from wire proto command')) 577 _('unhandled response type from wire proto command'))
569 578
570 if action == 'sendframes': 579 if action == 'sendframes':
598 def getargs(self, args): 607 def getargs(self, args):
599 data = {} 608 data = {}
600 for k in args.split(): 609 for k in args.split():
601 if k == '*': 610 if k == '*':
602 raise NotImplementedError('do not support * args') 611 raise NotImplementedError('do not support * args')
603 else: 612 elif k in self._args:
604 data[k] = self._args[k] 613 data[k] = self._args[k]
605 614
606 return [data[k] for k in args.split()] 615 return data
607 616
608 def getprotocaps(self): 617 def getprotocaps(self):
609 # Protocol capabilities are currently not implemented for HTTP V2. 618 # Protocol capabilities are currently not implemented for HTTP V2.
610 return set() 619 return set()
611 620