comparison mercurial/wireprotoframing.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 e9dea82ea1f3
children 01361be9e2dc
comparison
equal deleted inserted replaced
37484:c22fd3c4c23e 37485:0b7475ea38cf
347 payload=data) 347 payload=data)
348 348
349 if done: 349 if done:
350 break 350 break
351 351
352 def createbytesresponseframesfrombytes(stream, requestid, data, 352 def createbytesresponseframesfrombytes(stream, requestid, data, iscbor=False,
353 maxframesize=DEFAULT_MAX_FRAME_SIZE): 353 maxframesize=DEFAULT_MAX_FRAME_SIZE):
354 """Create a raw frame to send a bytes response from static bytes input. 354 """Create a raw frame to send a bytes response from static bytes input.
355 355
356 Returns a generator of bytearrays. 356 Returns a generator of bytearrays.
357 """ 357 """
358 358
359 # Simple case of a single frame. 359 # Simple case of a single frame.
360 if len(data) <= maxframesize: 360 if len(data) <= maxframesize:
361 flags = FLAG_BYTES_RESPONSE_EOS
362 if iscbor:
363 flags |= FLAG_BYTES_RESPONSE_CBOR
364
361 yield stream.makeframe(requestid=requestid, 365 yield stream.makeframe(requestid=requestid,
362 typeid=FRAME_TYPE_BYTES_RESPONSE, 366 typeid=FRAME_TYPE_BYTES_RESPONSE,
363 flags=FLAG_BYTES_RESPONSE_EOS, 367 flags=flags,
364 payload=data) 368 payload=data)
365 return 369 return
366 370
367 offset = 0 371 offset = 0
368 while True: 372 while True:
372 376
373 if done: 377 if done:
374 flags = FLAG_BYTES_RESPONSE_EOS 378 flags = FLAG_BYTES_RESPONSE_EOS
375 else: 379 else:
376 flags = FLAG_BYTES_RESPONSE_CONTINUATION 380 flags = FLAG_BYTES_RESPONSE_CONTINUATION
381
382 if iscbor:
383 flags |= FLAG_BYTES_RESPONSE_CBOR
377 384
378 yield stream.makeframe(requestid=requestid, 385 yield stream.makeframe(requestid=requestid,
379 typeid=FRAME_TYPE_BYTES_RESPONSE, 386 typeid=FRAME_TYPE_BYTES_RESPONSE,
380 flags=flags, 387 flags=flags,
381 payload=chunk) 388 payload=chunk)
606 if not meth: 613 if not meth:
607 raise error.ProgrammingError('unhandled state: %s' % self._state) 614 raise error.ProgrammingError('unhandled state: %s' % self._state)
608 615
609 return meth(frame) 616 return meth(frame)
610 617
611 def onbytesresponseready(self, stream, requestid, data): 618 def onbytesresponseready(self, stream, requestid, data, iscbor=False):
612 """Signal that a bytes response is ready to be sent to the client. 619 """Signal that a bytes response is ready to be sent to the client.
613 620
614 The raw bytes response is passed as an argument. 621 The raw bytes response is passed as an argument.
615 """ 622 """
616 ensureserverstream(stream) 623 ensureserverstream(stream)
617 624
618 def sendframes(): 625 def sendframes():
619 for frame in createbytesresponseframesfrombytes(stream, requestid, 626 for frame in createbytesresponseframesfrombytes(stream, requestid,
620 data): 627 data,
628 iscbor=iscbor):
621 yield frame 629 yield frame
622 630
623 self._activecommands.remove(requestid) 631 self._activecommands.remove(requestid)
624 632
625 result = sendframes() 633 result = sendframes()