wireprotov2: establish a type for representing command response
authorGregory Szorc <gregory.szorc@gmail.com>
Sat, 14 Apr 2018 11:46:08 -0700
changeset 37720 d715a85003c8
parent 37719 a656cba08a04
child 37721 f7673845b167
wireprotov2: establish a type for representing command response It will be desirable to have a higher-level type for representing command responses. This will allow us to do nicer things. For now, the instance encapsulates existing logic. It is still a bit primitive. But we're slowly making things better. Version 1 protocols have a wrapping layer that decodes the raw string data into a data structure and that data structure is sent to the future. Version 2 doesn't yet have this layer and the future is receiving the raw wire response. Hence why debugcommands needed to be taught about the response type. Differential Revision: https://phab.mercurial-scm.org/D3380
mercurial/debugcommands.py
mercurial/wireprotov2peer.py
--- a/mercurial/debugcommands.py	Sat Apr 14 11:50:19 2018 -0700
+++ b/mercurial/debugcommands.py	Sat Apr 14 11:46:08 2018 -0700
@@ -83,6 +83,7 @@
     vfs as vfsmod,
     wireprotoframing,
     wireprotoserver,
+    wireprotov2peer,
 )
 from .utils import (
     dateutil,
@@ -3012,7 +3013,16 @@
                 with peer.commandexecutor() as e:
                     res = e.callcommand(command, args).result()
 
-                ui.status(_('response: %s\n') % stringutil.pprint(res))
+                if isinstance(res, wireprotov2peer.commandresponse):
+                    if res.cbor:
+                        val = list(res.cborobjects())
+                    else:
+                        val = [res.b.getvalue()]
+
+                    ui.status(_('response: %s\n') % stringutil.pprint(val))
+
+                else:
+                    ui.status(_('response: %s\n') % stringutil.pprint(res))
 
         elif action == 'batchbegin':
             if batchedcommands is not None:
--- a/mercurial/wireprotov2peer.py	Sat Apr 14 11:50:19 2018 -0700
+++ b/mercurial/wireprotov2peer.py	Sat Apr 14 11:46:08 2018 -0700
@@ -17,6 +17,26 @@
     wireprotoframing,
 )
 
+class commandresponse(object):
+    """Represents the response to a command request."""
+
+    def __init__(self, requestid, command):
+        self.requestid = requestid
+        self.command = command
+
+        self.cbor = False
+        self.b = util.bytesio()
+
+    def cborobjects(self):
+        """Obtain decoded CBOR objects from this response."""
+        size = self.b.tell()
+        self.b.seek(0)
+
+        decoder = cbor.CBORDecoder(self.b)
+
+        while self.b.tell() < size:
+            yield decoder.decode()
+
 class clienthandler(object):
     """Object to handle higher-level client activities.
 
@@ -48,10 +68,7 @@
         rid = request.requestid
         self._requests[rid] = request
         self._futures[rid] = f
-        self._responses[rid] = {
-            'cbor': False,
-            'b': util.bytesio(),
-        }
+        self._responses[rid] = commandresponse(rid, command)
 
         return iter(())
 
@@ -104,28 +121,13 @@
         response = self._responses[frame.requestid]
 
         if action == 'responsedata':
-            response['b'].write(meta['data'])
+            response.b.write(meta['data'])
 
             if meta['cbor']:
-                response['cbor'] = True
+                response.cbor = True
 
             if meta['eos']:
-                if meta['cbor']:
-                    # If CBOR, decode every object.
-                    b = response['b']
-
-                    size = b.tell()
-                    b.seek(0)
-
-                    decoder = cbor.CBORDecoder(b)
-
-                    result = []
-                    while b.tell() < size:
-                        result.append(decoder.decode())
-                else:
-                    result = [response['b'].getvalue()]
-
-                self._futures[frame.requestid].set_result(result)
+                self._futures[frame.requestid].set_result(response)
 
                 del self._requests[frame.requestid]
                 del self._futures[frame.requestid]