Skip to content

Commit

Permalink
msgpack: add optional msgpack.v5 support
Browse files Browse the repository at this point in the history
The msgpack.v5 code located in msgpack_v5.go and
msgpack_v5_helper_test.go for tests. It is the same logic for
submodules.

An user can use msgpack.v5 with a build tag:
go_tarantool_msgpack_v5

Part of #124
  • Loading branch information
oleg-jukovec committed May 30, 2022
1 parent 19da011 commit 4a8fadc
Show file tree
Hide file tree
Showing 16 changed files with 303 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
- queue-utube handling (#85)
- Master discovery (#113)
- SQL support (#62)
- Optional msgpack.v5 usage (#124)

### Fixed

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ faster than other packages according to public benchmarks.
## Table of contents

* [Installation](#installation)
* [Build tags](#build-tags)
* [Documentation](#documentation)
* [API reference](#api-reference)
* [Walking\-through example](#walking-through-example)
* [msgpack.v5 migration](#msgpackv5-migration)
* [Contributing](#contributing)
* [Alternative connectors](#alternative-connectors)

Expand All @@ -51,6 +53,16 @@ This should put the source and binary files in subdirectories of
`github.com/tarantool/go-tarantool` to the `import {...}` section at the start
of any Go program.

### Build tags

To use `msgpack.v5` instead of `msgpack.v2` use the build tag:
```
go_tarantool_msgpack_v5
```
**Note:** In future releases, `msgpack.v5` may be used by default. We recommend
to read [msgpack.v5 migration notes](#msgpack.v5-migration) and try to
use msgpack.v5 before the changes.

## Documentation

Read the [Tarantool documentation][tarantool-doc-data-model-url]
Expand Down Expand Up @@ -121,6 +133,30 @@ There are two parameters:
* a space number (it could just as easily have been a space name), and
* a tuple.

### msgpack.v5 migration

Most the function names and argument types in `msgpack.v5` and `msgpack.v2`
have not changed (except at least `EncodeInt`, `EncodeUint` and `RegisterExt`).
But there are a lot of changes in a logic of encoding and deconding. On the plus
side the migration seems easy, but on the minus side you need to be very
careful.

First of all, `EncodeInt8`, `EncodeInt16`, `EncodeInt32`, `EncodeInt64`
and `EncodeUint*` analogues at `msgpack.v5` encode numbers as is without loss of
type. In `msgpack.v2` the type of a number is reduced to a value.

Secondly, a base decoding function does not convert numbers to `int64` or
`uint64`. The change makes manual type conversions much more difficult and can
lead to runtime erros with an old code. We recommend not use type conversions
and give preference to `*Typed` functions (besides, it's faster).

There are also changes in the logic that can lead to errors in the old code,
[as example](https://github.com/vmihailenco/msgpack/issues/327). Although in
`msgpack.v5` has added some functions for the logic tuning see
[UseLooseInterfaceDecoding](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Decoder.UseLooseInterfaceDecoding), [UseCompactInts](https://pkg.go.dev/github.com/vmihailenco/msgpack/v5#Encoder.UseCompactInts) etc, but it is still impossible
to achieve full compliance of behavior between `msgpack.v5` and `msgpack.v2`. So
we don't go this way. We use standart settings if it possible.

## Contributing

See [the contributing guide](CONTRIBUTING.md) for detailed instructions on how
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ require (
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/vmihailenco/msgpack.v2 v2.9.2
github.com/vmihailenco/msgpack/v5 v5.3.5
)
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
Expand Down
29 changes: 16 additions & 13 deletions msgpack.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !go_tarantool_msgpack_v5
// +build !go_tarantool_msgpack_v5

package tarantool

import (
Expand Down Expand Up @@ -54,53 +57,53 @@ func msgpackIsString(code byte) bool {
}

func (s *single) DecodeMsgpack(d *msgpack.Decoder) error {
return s.decodeMsgpackImpl(&Decoder{d})
return s.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (space *Space) DecodeMsgpack(d *msgpack.Decoder) error {
return space.decodeMsgpackImpl(&Decoder{d})
return space.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (field *Field) DecodeMsgpack(d *msgpack.Decoder) error {
return field.decodeMsgpackImpl(&Decoder{d})
return field.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (index *Index) DecodeMsgpack(d *msgpack.Decoder) error {
return index.decodeMsgpackImpl(&Decoder{d})
return index.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (indexField *IndexField) DecodeMsgpack(d *msgpack.Decoder) error {
return indexField.decodeMsgpackImpl(&Decoder{d})
return indexField.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (meta *ColumnMetaData) DecodeMsgpack(d *msgpack.Decoder) error {
return meta.decodeMsgpackImpl(&Decoder{d})
return meta.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (info *SQLInfo) DecodeMsgpack(d *msgpack.Decoder) error {
return info.decodeMsgpackImpl(&Decoder{d})
return info.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (k IntKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{enc})
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (k UintKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{enc})
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (k StringKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{enc})
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (k IntIntKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{enc})
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (o Op) EncodeMsgpack(enc *msgpack.Encoder) error {
return o.encodeMsgpackImpl(&Encoder{enc})
return o.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (o OpSplice) EncodeMsgpack(enc *msgpack.Encoder) error {
return o.encodeMsgpackImpl(&Encoder{enc})
return o.encodeMsgpackImpl(&Encoder{Encoder: enc})
}
11 changes: 7 additions & 4 deletions msgpack_helper_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !go_tarantool_msgpack_v5
// +build !go_tarantool_msgpack_v5

package tarantool_test

import (
Expand All @@ -6,17 +9,17 @@ import (
)

func (m *Member) EncodeMsgpack(e *msgpack.Encoder) error {
return m.encodeMsgpackImpl(&Encoder{e})
return m.encodeMsgpackImpl(&Encoder{Encoder: e})
}

func (m *Member) DecodeMsgpack(d *msgpack.Decoder) error {
return m.decodeMsgpackImpl(&Decoder{d})
return m.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (c *Tuple2) EncodeMsgpack(e *msgpack.Encoder) error {
return c.encodeMsgpackImpl(&Encoder{e})
return c.encodeMsgpackImpl(&Encoder{Encoder: e})
}

func (c *Tuple2) DecodeMsgpack(d *msgpack.Decoder) error {
return c.decodeMsgpackImpl(&Decoder{d})
return c.decodeMsgpackImpl(&Decoder{Decoder: d})
}
112 changes: 112 additions & 0 deletions msgpack_v5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//go:build go_tarantool_msgpack_v5
// +build go_tarantool_msgpack_v5

package tarantool

import (
"io"

"github.com/vmihailenco/msgpack/v5"
"github.com/vmihailenco/msgpack/v5/msgpcode"
)

type Encoder struct {
*msgpack.Encoder
}

type Decoder struct {
*msgpack.Decoder
}

func newEncoder(w io.Writer) *Encoder {
enc := msgpack.NewEncoder(w)
return &Encoder{Encoder: enc}
}

func newDecoder(r io.Reader) *Decoder {
dec := msgpack.NewDecoder(r)
dec.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
return dec.DecodeUntypedMap()
})
return &Decoder{Decoder: dec}
}

func (e *Encoder) encodeUintImpl(v uint64) error {
return e.EncodeUint(v)
}

func (e *Encoder) encodeIntImpl(v int64) error {
return e.EncodeInt(v)
}

func msgpackIsUint(code byte) bool {
return code == msgpcode.Uint8 || code == msgpcode.Uint16 ||
code == msgpcode.Uint32 || code == msgpcode.Uint64 ||
msgpcode.IsFixedNum(code)
}

func msgpackIsMap(code byte) bool {
return code == msgpcode.Map16 || code == msgpcode.Map32 || msgpcode.IsFixedMap(code)
}

func msgpackIsArray(code byte) bool {
return code == msgpcode.Array16 || code == msgpcode.Array32 ||
msgpcode.IsFixedArray(code)
}

func msgpackIsString(code byte) bool {
return msgpcode.IsFixedString(code) || code == msgpcode.Str8 ||
code == msgpcode.Str16 || code == msgpcode.Str32
}

func (s *single) DecodeMsgpack(d *msgpack.Decoder) error {
return s.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (space *Space) DecodeMsgpack(d *msgpack.Decoder) error {
return space.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (field *Field) DecodeMsgpack(d *msgpack.Decoder) error {
return field.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (index *Index) DecodeMsgpack(d *msgpack.Decoder) error {
return index.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (indexField *IndexField) DecodeMsgpack(d *msgpack.Decoder) error {
return indexField.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (meta *ColumnMetaData) DecodeMsgpack(d *msgpack.Decoder) error {
return meta.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (info *SQLInfo) DecodeMsgpack(d *msgpack.Decoder) error {
return info.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (k IntKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (k UintKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (k StringKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (k IntIntKey) EncodeMsgpack(enc *msgpack.Encoder) error {
return k.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (o Op) EncodeMsgpack(enc *msgpack.Encoder) error {
return o.encodeMsgpackImpl(&Encoder{Encoder: enc})
}

func (o OpSplice) EncodeMsgpack(enc *msgpack.Encoder) error {
return o.encodeMsgpackImpl(&Encoder{Encoder: enc})
}
25 changes: 25 additions & 0 deletions msgpack_v5_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build go_tarantool_msgpack_v5
// +build go_tarantool_msgpack_v5

package tarantool_test

import (
. "github.com/tarantool/go-tarantool"
"github.com/vmihailenco/msgpack/v5"
)

func (m *Member) EncodeMsgpack(e *msgpack.Encoder) error {
return m.encodeMsgpackImpl(&Encoder{Encoder: e})
}

func (m *Member) DecodeMsgpack(d *msgpack.Decoder) error {
return m.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (c *Tuple2) EncodeMsgpack(e *msgpack.Encoder) error {
return c.encodeMsgpackImpl(&Encoder{Encoder: e})
}

func (c *Tuple2) DecodeMsgpack(d *msgpack.Decoder) error {
return c.decodeMsgpackImpl(&Decoder{Decoder: d})
}
3 changes: 3 additions & 0 deletions queue/msgpack.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !go_tarantool_msgpack_v5
// +build !go_tarantool_msgpack_v5

package queue

import (
Expand Down
3 changes: 3 additions & 0 deletions queue/msgpack_helper_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !go_tarantool_msgpack_v5
// +build !go_tarantool_msgpack_v5

package queue_test

import (
Expand Down
17 changes: 17 additions & 0 deletions queue/msgpack_v5.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//go:build go_tarantool_msgpack_v5
// +build go_tarantool_msgpack_v5

package queue

import (
"github.com/tarantool/go-tarantool"
"github.com/vmihailenco/msgpack/v5"
)

func (qd *queueData) DecodeMsgpack(d *msgpack.Decoder) error {
return qd.decodeMsgpackImpl(&tarantool.Decoder{Decoder: d})
}

func (t *Task) DecodeMsgpack(d *msgpack.Decoder) error {
return t.decodeMsgpackImpl(&tarantool.Decoder{Decoder: d})
}
25 changes: 25 additions & 0 deletions queue/msgpack_v5_helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build go_tarantool_msgpack_v5
// +build go_tarantool_msgpack_v5

package queue_test

import (
. "github.com/tarantool/go-tarantool"
"github.com/vmihailenco/msgpack/v5"
)

func (c *customData) DecodeMsgpack(d *msgpack.Decoder) error {
return c.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (c *customData) EncodeMsgpack(e *msgpack.Encoder) error {
return c.encodeMsgpackImpl(&Encoder{Encoder: e})
}

func (c *dummyData) DecodeMsgpack(d *msgpack.Decoder) error {
return c.decodeMsgpackImpl(&Decoder{Decoder: d})
}

func (c *dummyData) EncodeMsgpack(e *msgpack.Encoder) error {
return c.encodeMsgpackImpl(&Encoder{Encoder: e})
}
3 changes: 3 additions & 0 deletions uuid/msgpack.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//go:build !go_tarantool_msgpack_v5
// +build !go_tarantool_msgpack_v5

package uuid

import (
Expand Down
Loading

0 comments on commit 4a8fadc

Please sign in to comment.