-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
encoding/gob: permit registering duplicate names #36345
Comments
@dsnet - at the end of your issue, you said:
That first line doesnt work because RegisterName takes two parameters. Did you mean this? gob.Register(Rect{})
gob.RegisterName("main.Rect", Rect{}) because that does raise:
When types are moved with aliases the only way to inform gob is to leave out the first line: // gob.Register(Rect{}) --- ng. Rect is now an alias to Rect2{}
gob.RegisterName("main.Rect", Rect{}) or, this works the same and might be clearer: gob.RegisterName("main.Rect", Rect2{}) // Rect has moved to Rect2 That doesn't seem too terrible because the code also had to be altered to add the alias. But, It does feel a little unexpected ( re: better docs ), and it does "lock" the type forever to the earlier name. I just encountered similar issues trying to implement transparent type migration... "upgrading" to new types while reading/writing. To support type migration, it might be nice ( like your RegisterAlias()? ) if the decoder allowed multiple names to map to the same type. That would allow "main.Rect" and "main.Rect2" names to be loaded into a "Rect2" struct. If the encoder still always used a type's actual name ( ie. "main.Rect2" ) that would effectively move the type after a read and write. I wasn't able to find similar requests, but encapsulating the registry and creating the de/encoder(s) from it could also do the trick. // possible syntax:
var oldFormat, newFormat gob.Registry
oldFormat.RegisterName("main.Rect", Rect2{})
newFormat.Register(Rect2{})
dec, enc:= oldFormat.NewDecoder(), newFormat.NewEncoder() As a side benefit, registry memory could be released once it's no longer needed. And... taking this a step further... if that registry object exposed a way to translate type names into gob.Decoder and gob.Encoder interfaces... that would allow a level of flexibility for stream translation and migration that's not currently available. |
please add RegisterAlias |
In go1.9, type aliases were introduced. The purpose of type aliases is to permit the movement of types from one location to another. This implies:
The use of type aliases interacts poorly with gob-encoded data stored on disk that represent interface values as
gob
was a developed in an era where there was one-to-one relationship between types and names.Consider the following examples.
At some point in the past, we gob-encoded is stored on disk using something like:
On the decoder side, this works fine with code like:
At some point in the future, suppose we move
Rect
, now decoding fails:The problem is that the full type name is encoded in the gob wire data. Trying to decode the data at a later date does not know about the movement of the type due to type aliases.
Given that problem, one would think that you could just use
gob.RegisterName
to manually register the old name:However, that panics with:
I propose the following changes:
gob
be better documented about the interaction of type aliases and serialization of interface values.gob.RegisterName
be relaxed to permit duplicate names. However, this can cause confusion in the implementation as to which name to use when marshaling. Alternatively, we could add agob.RegisterAlias
that makes it clear that the duplicate names are aliases.The text was updated successfully, but these errors were encountered: