You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Theres a bug in how the serializer is used within the table that doubles the pointers for types, and prevents the usage of Protobufs as Table types without weird/unnecessary reflection and pointer dereferencing.
ie:
/* defined proto message:message MyMessage { ...}*/// Generated from protobuf// with pointer recievers on all methdstypeMyMessagestruct { ... }
funcmain() {
// explicit parameter type declaration for clarityopts:=bond.DefaultOptions()
opts.Serializer=protoSerializer{}
bond=bond.Open(opts)
myTable=bond.NewTable[*MyMessage](bond.TableOptions[*MyMessage]{
...
})
myTable.Exists(&MyMessage{...}) // this will error
}
The issue stems from the fact that values passed to the Serializer within the Table code, have an additional pointer to them.
Like right here (there are a couple of spots, this is just one):
This adds an additional pointer, but doesn't actually provide any additional value as far as I can tell. Testing locally on my fork, you can remove the additional & pointer reference, and everything still works (passes all tests).
I suspect it works because the builtin serializers (cbor, json, and msgpack) all do their own recursive pointer indirection, when they call <codec>.Marshal(i). So an additional pointer doesn't cause any issues.
However, in the protobuf serializer code above, it needs a proto.Message type, not an interface{} type, unlike the other codec marshallers. So when the p, ok := i.(proto.Message) runs, it won't pass the type assertion, since the underlying type of i isn't *MyMessage (which does implement proto.Message) but **MyMessage (double pointer, which doesn't implement proto.Message)
The protoSerializer code can be modified to work by checking the reflect.TypeOf(i), and if its a pointer, dereference, and recusively calling Serialize, but obviously I'd like to avoid that.
The other alternative is to not use bond.Table[*MyMessage] as the table parameter, but when using protobufs, all the generated code is with pointer recievers, so the unnecessary dereference would just happen elsewhere in my code. Ideally the extra & in the table code can be removed, and this kind of usecase can be cleanly implemented.
--
ps. Enjoying bond 👍 - thanks
The text was updated successfully, but these errors were encountered:
Theres a bug in how the serializer is used within the table that doubles the pointers for types, and prevents the usage of Protobufs as Table types without weird/unnecessary reflection and pointer dereferencing.
ie:
With the following serializer implementation:
The issue stems from the fact that values passed to the
Serializer
within the Table code, have an additional pointer to them.Like right here (there are a couple of spots, this is just one):
bond/table.go
Line 403 in 6192574
This adds an additional pointer, but doesn't actually provide any additional value as far as I can tell. Testing locally on my fork, you can remove the additional
&
pointer reference, and everything still works (passes all tests).I suspect it works because the builtin serializers (
cbor
,json
, andmsgpack
) all do their own recursive pointer indirection, when they call<codec>.Marshal(i)
. So an additional pointer doesn't cause any issues.However, in the protobuf serializer code above, it needs a
proto.Message
type, not aninterface{}
type, unlike the other codec marshallers. So when thep, ok := i.(proto.Message)
runs, it won't pass the type assertion, since the underlying type ofi
isn't*MyMessage
(which does implementproto.Message
) but**MyMessage
(double pointer, which doesn't implementproto.Message
)The
protoSerializer
code can be modified to work by checking thereflect.TypeOf(i)
, and if its a pointer, dereference, and recusively callingSerialize
, but obviously I'd like to avoid that.The other alternative is to not use
bond.Table[*MyMessage]
as the table parameter, but when using protobufs, all the generated code is with pointer recievers, so the unnecessary dereference would just happen elsewhere in my code. Ideally the extra&
in the table code can be removed, and this kind of usecase can be cleanly implemented.--
ps. Enjoying bond 👍 - thanks
The text was updated successfully, but these errors were encountered: