wireprotov2: define type to represent pre-encoded object
An upcoming commit will introduce a caching layer to command
serving. This will require the ability to cache pre-encoded data.
This commit introduces a type to represent pre-encoded data and
teaches the output layer to not CBOR encode an instance of that
type.
Differential Revision: https://phab.mercurial-scm.org/D4772
--- a/mercurial/wireprotoframing.py Wed Sep 26 15:53:49 2018 -0700
+++ b/mercurial/wireprotoframing.py Wed Sep 26 17:16:27 2018 -0700
@@ -22,6 +22,7 @@
encoding,
error,
util,
+ wireprototypes,
)
from .utils import (
cborutil,
@@ -840,10 +841,22 @@
yield createcommandresponseokframe(stream, requestid)
emitted = True
- for chunk in cborutil.streamencode(o):
- for frame in emitter.send(chunk):
+ # Objects emitted by command functions can be serializable
+ # data structures or special types.
+ # TODO consider extracting the content normalization to a
+ # standalone function, as it may be useful for e.g. cachers.
+
+ # A pre-encoded object is sent directly to the emitter.
+ if isinstance(o, wireprototypes.encodedresponse):
+ for frame in emitter.send(o.data):
yield frame
+ # A regular object is CBOR encoded.
+ else:
+ for chunk in cborutil.streamencode(o):
+ for frame in emitter.send(chunk):
+ yield frame
+
except Exception as e:
for frame in createerrorframe(stream, requestid,
'%s' % e,
--- a/mercurial/wireprototypes.py Wed Sep 26 15:53:49 2018 -0700
+++ b/mercurial/wireprototypes.py Wed Sep 26 17:16:27 2018 -0700
@@ -10,6 +10,9 @@
hex,
)
from .i18n import _
+from .thirdparty import (
+ attr,
+)
from . import (
error,
util,
@@ -352,3 +355,15 @@
', '.sorted(validnames))
return compengines
+
+@attr.s
+class encodedresponse(object):
+ """Represents response data that is already content encoded.
+
+ Wire protocol version 2 only.
+
+ Commands typically emit Python objects that are encoded and sent over the
+ wire. If commands emit an object of this type, the encoding step is bypassed
+ and the content from this object is used instead.
+ """
+ data = attr.ib()