-
Notifications
You must be signed in to change notification settings - Fork 309
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
Migrate away from gogo/protobuf #2798
Comments
Validation plugin we're using dropped support for GoGo |
I think the best way forward is to follow the ecosystem and migrate away from gogo/protobuf. With more and more of our other dependencies moving away from gogo, I think it will become increasingly difficult to keep using it. Of course it's going to be a lot of work to migrate, so if we do it, we need to come up with a good plan. @rvolosatovs probably knows more about the custom options that are set in our
Maybe this is also a good time to start thinking about our v4 API, because I can imagine we might discover some more (API breaking) surprises. |
I think the best way forward would be to first try out https://github.com/alta/protopatch. Depending on the result:
Looking forward, I don't think we should be directly using vanilla protobuf protos in components internally at runtime(given the provided feature set of protobuf today).
|
Refs also #342 (generated populators) |
I'm not in favor of a (smaller) alternative to gogo. It feels like pushing the can. Let's keep things as vanilla as possible, especially when we need to decide again what the best way forward is. I do agree that we can consider using intermediary types in some places, instead of relying everywhere on the generated protos. It's basically separating data transfer objects (DTOs: protos, also for storage) from data access objects (DAOs: how we use them). If that is primarily reading, we can also declare interfaces and see how far we get with that. That said, I wouldn't go as far as changing the entire NS to using |
Let's move this discussion to November |
@rvolosatovs what is your objection against moving to vanilla with a custom JSON marshaler? |
The huge migration burden and loads of boilerplate if we end up just using vanilla protos directly. |
I'm afraid that any plugin that we start to rely on will end up in an unmaintained state at some point. Generally speaking, I'm in favor of keeping things as close to vanilla as possible. If that means |
I'm afraid that refactoring our entire codebase is going to be a pain no matter how we do it. Our (gogo-generated) proto structs are used everywhere right now (gRPC API, HTTP API, events, errors, internally, Redis DB, ...), so changing to something else (whatever that other thing is) is going to touch pretty much everything in our codebase, and the way it looks now, all at the same time. The hard requirement is that we don't break compatibility of our v3 API. Even if we decide to use this situation as the moment to start working on a v4 API (at least internally), we will still have to keep supporting that v3 API for existing users. In the long term, I think we would do ourselves a big favor by decoupling our (versioned, stable-within-major) external APIs from our internal (unversioned, stable-within-minor) API and our (versioned, stable) database documents. We could then write or generate functions to convert between our internal APIs and the others. But I think there are some steps that we can already take now: JSONIn order to keep our v3 JSON API compatible, I think our first TODO is to work on generating JSON marshalers and unmarshalers that understand how to marshal/unmarshal our custom types. I think doing this is smart anyway because there is no stability promise for Go's implementation of the JSON format for protocol buffers, so we better have control over that ourselves. Doing this could also allow us to consider field masks when marshaling to JSON. In the Generate new protos next to the old onesI already tried that here: a41f62d This does make protobuf complain about the types registry, so we may need to remove Generate functions to convert between old and new protosThis is for the transition period only, but for the long term solution, we'd want to generate similar converters. Update services one by oneI already tried that with a simple service here: cd7d75c, but for more complicated services we'd definitely need those converters. Note that this only changes the grpc service itself. The grpc-gateway still uses the old gogo stuff on the JSON side, and then calls the internal gRPC server, which then runs the new implementation. |
Pushed some initial dependency updates and backwards compatibility work-arounds here: https://github.com/TheThingsNetwork/lorawan-stack/compare/issue/2798-codec |
I've built two new releases of I've updated the tooling in a separate branch to use the new Please sample some files and let me know what you think. If things look good, we can start implementing the commits from #2798 (comment) on that branch, and finally move to API v2. |
Migration status update:
In order to speedup the development, we can already start backporting some changes from https://github.com/TheThingsIndustries/lorawan-stack/pull/3445 in order to lower the diff:
|
Migration status update:
After the Christmas holidays we can start merging back this mammoth change in enterprise and open source. The only problem to settle is backwards compatibility with respect to the JSON API. The context is as follows:
@ysmilda has implemented (1) which allows us to generate the marshallers for every message, thus ensuring that at least we use the same style everywhere, and (2) allows us to choose which style we want to use. In https://github.com/TheThingsIndustries/lorawan-stack/pull/3445 I actually 'broke back' the API to render all field masks as objects, in order to keep consistence over time. My argument here is that for most of v3's lifetime and for all of the code in the wild, the object form is what is used. Are there any objections to 'breaking the API' a second time to keep things consistent to what they were a year ago ? Our JSON is not JSONPb anyway (custom renderers, custom enum marshaling). @johanstokking @KrishnaIyer Unmarshalling fieldmasks is not a problem - |
Yes I prefer consistency, even if we need to break the JSON API. |
Summary
https://github.com/gogo/protobuf is not mantained any more gogo/protobuf#691 (currently)
Why do we need this?
It's our dependency, which is incompatible with new
golang/protobuf
version, which more and more packages depend on, hence we need to replace thegolang/protobuf
version, depending on outdated versions of our direct dependencies and potentially even breaking packages this wayWhat is already there? What do you see now?
gogo/protobuf
dependencyWhat is missing? What do you want to see?
Figure this out
How do you propose to implement this?
Figure out if a new maintainer will appear or different plugin with feature parity?
Use just vanilla protobuf?
How do you propose to test this?
tests
Can you do this yourself and submit a Pull Request?
yes
The text was updated successfully, but these errors were encountered: