Use messagepack extensions payloads that can be transmitted#16
Use messagepack extensions payloads that can be transmitted#16notmgsk wants to merge 5 commits intombrezu:masterfrom
Conversation
|
Hi, thanks, this looks good. I'll try to watch your progress; but please be sure to notify me when you think you're ready! I just pushed a commit that should make your |
As far as I have been able to understand, cl-messagepack's current
implementation of extensions doesn't allow you to encode arbitrary
data, associate it with some type, and then communicate this across a
network. cl-messagepack's implementation is more like you have some
instance of an object, you assign an ID to it, you can then
communicate this ID across the network and back, and then lookup this
object in a hashtable using the ID. This restricts you to keeping the
data in the same lisp image / memory.
This is a first stab at what I think is a "true" implementation of
messagepack's extensions. It is incomplete, but I'm making the PR for
visibility.
Use it to encode complex floats with the following:
```
(defun my-encode-complex (data stream)
(encode-fixext-8
(append
(rest (coerce (flexi-streams:with-output-to-sequence (s) (encode-float (realpart data) s)) 'list))
(rest (coerce (flexi-streams:with-output-to-sequence (s) (encode-float (imagpart data) s)) 'list)))
stream
0))
(defun my-decode-complex (len stream)
(complex (sb-kernel:make-single-float (ub32->sb32 (load-big-endian stream 4)))
(sb-kernel:make-single-float (ub32->sb32 (load-big-endian stream 4))))
;; (or #+sbcl (sb-kernel:make-single-float (ub32->sb32 (load-big-endian stream 4)))
;; #-(or sbcl) (error "No floating point support yet."))
;; (or #+sbcl (sb-kernel:make-double-float (ub32->sb32 (load-big-endian stream 4))
;; (load-big-endian stream 4))
;; #+ccl (ccl::double-float-from-bits (load-big-endian stream 4)
;; (load-big-endian stream 4))
;; #-(or sbcl ccl) (error "No floating point support yet."))
)
(register-extension-dispatcher 0 #'complexp #'my-encode-complex
CL-USER> (mpk::decode (mpk::encode (list #C(1.2 1.3)
#C(0.0 1.0)
(list #C(1.2 1.3)))))
```
1926be5 to
7766bca
Compare
|
@phmarek I think it's in a review-able state now. I've added tests. With your changes, the encoding of complex floats looks like I'm not married to this interface, and would be more than happy to hear your thoughts and suggestions. |
|
Thanks. A few questions - but please don't just change your code, let's discuss that first.
|
|
Thanks for the feedback!
This will be removed, and can be ignored for now.
Do you mean if (defun %serialize-complex (data stream)
(mpk::encode-fixext-16 (append (mpk::encode (realpart data) t)
(mpk::encode (imagpart data) t))
stream
0))
Do you mean something that rebinds (defmacro with-extensions ((extensions-ht) &body body)
`(let ((mpk::*extension-dispatchers* ,extensions-ht))
,@body))
The data structure used here could definitely be improved. Will think about how to do that.
This one is tough. My sense is that the implementations are sufficiently different that they are not compatible. Maybe with some clever hacking they could be. |
|
Hi Mark!
An alternative would be to
investigate whether we could pass `&optional drop-prefix` to
`mpk:encode` which is then passed on to all further `mpk:encode-*`
functions.
That might be another idea, yes.
Please investigate and get back to me whether it looks better in
practice ;)
Do you mean something that rebinds `mpk::*extension-dispatchers*`?
Yeah, a `WITH-` macro, and the registration needs to be able to write
into a non-default hashtable.
> * What about compatibility with users of the old extension system?
This one is tough. My sense is that the implementations are
sufficiently different that they are not compatible. Maybe with some
clever hacking they could be.
Well, what was the reason you started anew?
Perhaps we should separate the old and the new way into different files,
and have them with #+mpk-marks-extensions and #-mpk-marks-extensions
in the .ASD file (please note that I'm avoiding "new", as that would
get old within a few years ;)
|
Will do.
Sounds reasonable.
To answer the first part of that: I don't think the old implementation was generally useful. You couldn't for example encode arbitrary data, send it over a network to a completely separate process, and then decode it -- which is a problem that I think messagepack's extensions were meant to solve. |
As far as I have been able to understand, cl-messagepack's current
implementation of extensions doesn't allow you to encode arbitrary
data, associate it with some type, and then communicate this across a
network. cl-messagepack's implementation is more like you have some
instance of an object, you assign an ID to it, you can then
communicate this ID across the network and back, and then lookup this
object in a hashtable using the ID. This restricts you to keeping the
data in the same lisp image / memory.
This is a first stab at what I think is a "true" implementation of
messagepack's extensions. It is incomplete, but I'm making the PR for
visibility.
Use it to encode complex floats with the following: