D2899: wireproto: define attr-based classes for representing frames

2018-03-21 Thread indygreg (Gregory Szorc)
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

2018-03-19 Thread indygreg (Gregory Szorc)
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.