D2899: wireproto: define attr-based classes for representing frames
This revision was automatically updated to reflect the committed changes. Closed by commit rHG884a0c1604ad: wireproto: define attr-based classes for representing frames (authored by indygreg, committed by ). REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D2899?vs=7131=7237 REVISION DETAIL https://phab.mercurial-scm.org/D2899 AFFECTED FILES mercurial/wireprotoframing.py mercurial/wireprotoserver.py tests/test-wireproto-serverreactor.py CHANGE DETAILS diff --git a/tests/test-wireproto-serverreactor.py b/tests/test-wireproto-serverreactor.py --- a/tests/test-wireproto-serverreactor.py +++ b/tests/test-wireproto-serverreactor.py @@ -18,11 +18,14 @@ Emits a generator of results from ``onframerecv()`` calls. """ for frame in gen: -rid, frametype, frameflags, framelength = framing.parseheader(frame) +header = framing.parseheader(frame) payload = frame[framing.FRAME_HEADER_SIZE:] -assert len(payload) == framelength +assert len(payload) == header.length -yield reactor.onframerecv(rid, frametype, frameflags, payload) +yield reactor.onframerecv(framing.frame(header.requestid, +header.typeid, +header.flags, +payload)) def sendcommandframes(reactor, rid, cmd, args, datafh=None): """Generate frames to run a command and send them to a reactor.""" diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -400,12 +400,11 @@ states.append(b'received: ') break -requestid, frametype, frameflags, payload = frame -states.append(b'received: %d %d %d %s' % (frametype, frameflags, - requestid, payload)) +states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags, + frame.requestid, + frame.payload)) -action, meta = reactor.onframerecv(requestid, frametype, frameflags, - payload) +action, meta = reactor.onframerecv(frame) states.append(json.dumps((action, meta), sort_keys=True, separators=(', ', ': '))) @@ -434,7 +433,7 @@ if not frame: break -action, meta = reactor.onframerecv(*frame) +action, meta = reactor.onframerecv(frame) if action == 'wantframe': # Need more data before we can do anything. diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py --- a/mercurial/wireprotoframing.py +++ b/mercurial/wireprotoframing.py @@ -14,6 +14,9 @@ import struct from .i18n import _ +from .thirdparty import ( +attr, +) from . import ( error, util, @@ -92,6 +95,24 @@ ARGUMENT_FRAME_HEADER = struct.Struct(r'> 4 frameflags = typeflags & 0x0f -return requestid, frametype, frameflags, framelength +return frameheader(framelength, requestid, frametype, frameflags) def readframe(fh): """Read a unified framing protocol frame from a file object. @@ -184,14 +205,14 @@ raise error.Abort(_('received incomplete frame: got %d bytes: %s') % (readcount, header)) -requestid, frametype, frameflags, framelength = parseheader(header) +h = parseheader(header) -payload = fh.read(framelength) -if len(payload) != framelength: +payload = fh.read(h.length) +if len(payload) != h.length: raise error.Abort(_('frame length error: expected %d; got %d') % - (framelength, len(payload))) + (h.length, len(payload))) -return requestid, frametype, frameflags, payload +return frame(h.requestid, h.typeid, h.flags, payload) def createcommandframes(requestid, cmd, args, datafh=None): """Create frames necessary to transmit a request to run a command. @@ -433,7 +454,7 @@ # request id -> dict of commands that are actively being received. self._receivingcommands = {} -def onframerecv(self, requestid, frametype, frameflags, payload): +def
D2899: wireproto: define attr-based classes for representing frames
indygreg created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY When frames only had 3 attributes, it was reasonable to represent them as a tuple. With them growing more attributes, it will be easier to pass them around as a more formal type. So let's define attr-based classes to represent frame headers and full frames. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D2899 AFFECTED FILES mercurial/wireprotoframing.py mercurial/wireprotoserver.py tests/test-wireproto-serverreactor.py CHANGE DETAILS diff --git a/tests/test-wireproto-serverreactor.py b/tests/test-wireproto-serverreactor.py --- a/tests/test-wireproto-serverreactor.py +++ b/tests/test-wireproto-serverreactor.py @@ -18,11 +18,14 @@ Emits a generator of results from ``onframerecv()`` calls. """ for frame in gen: -rid, frametype, frameflags, framelength = framing.parseheader(frame) +header = framing.parseheader(frame) payload = frame[framing.FRAME_HEADER_SIZE:] -assert len(payload) == framelength +assert len(payload) == header.length -yield reactor.onframerecv(rid, frametype, frameflags, payload) +yield reactor.onframerecv(framing.frame(header.requestid, +header.typeid, +header.flags, +payload)) def sendcommandframes(reactor, rid, cmd, args, datafh=None): """Generate frames to run a command and send them to a reactor.""" diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -400,12 +400,11 @@ states.append(b'received: ') break -requestid, frametype, frameflags, payload = frame -states.append(b'received: %d %d %d %s' % (frametype, frameflags, - requestid, payload)) +states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags, + frame.requestid, + frame.payload)) -action, meta = reactor.onframerecv(requestid, frametype, frameflags, - payload) +action, meta = reactor.onframerecv(frame) states.append(json.dumps((action, meta), sort_keys=True, separators=(', ', ': '))) @@ -434,7 +433,7 @@ if not frame: break -action, meta = reactor.onframerecv(*frame) +action, meta = reactor.onframerecv(frame) if action == 'wantframe': # Need more data before we can do anything. diff --git a/mercurial/wireprotoframing.py b/mercurial/wireprotoframing.py --- a/mercurial/wireprotoframing.py +++ b/mercurial/wireprotoframing.py @@ -14,6 +14,9 @@ import struct from .i18n import _ +from .thirdparty import ( +attr, +) from . import ( error, util, @@ -92,6 +95,24 @@ ARGUMENT_FRAME_HEADER = struct.Struct(r'> 4 frameflags = typeflags & 0x0f -return requestid, frametype, frameflags, framelength +return frameheader(framelength, requestid, frametype, frameflags) def readframe(fh): """Read a unified framing protocol frame from a file object. @@ -184,14 +205,14 @@ raise error.Abort(_('received incomplete frame: got %d bytes: %s') % (readcount, header)) -requestid, frametype, frameflags, framelength = parseheader(header) +h = parseheader(header) -payload = fh.read(framelength) -if len(payload) != framelength: +payload = fh.read(h.length) +if len(payload) != h.length: raise error.Abort(_('frame length error: expected %d; got %d') % - (framelength, len(payload))) + (h.length, len(payload))) -return requestid, frametype, frameflags, payload +return frame(h.requestid, h.typeid, h.flags, payload) def createcommandframes(requestid, cmd, args, datafh=None): """Create frames necessary to transmit a request to run a command. @@ -433,7 +454,7 @@ # request id -> dict of commands that are actively being received.