Сегодня поговорим о недавно обновленном ходу.protobuf
история. Процесс замечательный (твист) 😳
Два дня назад проектdependabot
пакет чаевыхgithub.com/golang/protobuf
Доступна сV1.3.5
обновитесь доV1.4.0
Round One
Я думал, что будет нормально обновиться напрямую, но без CI я нашел старую версию (V1.3.5
) В тестовом коде используется сгенерированный код pbXXX_Size()
метод расчета размера сообщения
в новой версии(v1.4.0
)внутриpanic
охватывать
Давайте посмотрим, чем они отличаются:
Для упрощения используем официальный файл protohelloworld.proto
СозданV1.3.5
версия файла pb
curl -O https://raw.githubusercontent.com/grpc/grpc-go/master/examples/helloworld/helloworld/helloworld.proto
brew install protobuf
GO111MODULE=on go get -u github.com/golang/protobuf/protoc-gen-go@v1.3.5
protoc --go_out=plugins=grpc:. helloworld.proto
заменить сноваgithub.com/golang/protobuf/protoc-gen-go@v1.4.0
, создать новую версию pb-файла
найтиXXX_Size
функция
В старой версии проблем нет
// helloword.pb.go
func (m *HelloRequest) XXX_Size() int {
return xxx_messageInfo_HelloRequest.Size(m)
}
var xxx_messageInfo_HelloRequest proto.InternalMessageInfo
// github.com/golang/protobuf@v1.3.5/proto/table_marshal.go
func (a *InternalMessageInfo) Size(msg Message) int {
В новой версии файла pb больше нетInternalMessageInfo
Типы
Но его можно найти в исходниках, он заброшен.
// github.com/golang/protobuf@v1.4.0/proto/deprecated.go
// Deprecated: Do not use.
type InternalMessageInfo struct{}
func (*InternalMessageInfo) Size(Message) int { panic("not implemented") }
// 同样废弃的还有: DiscardUnknown, Marshal, Merge, Unmarshal
Как получить размер в новой версии кода?
Посмотрите пример в исходном коде,proto.Size(m Message) int
может быть реализован
InternalMessageInfo
также стать интерфейсомtype Message = protoiface.MessageV1
этоInternalMessageInfo
Устаревание также упоминается в обновлении версии, см. подробностиgenerated-code
ОК, метод замены, первый раунд окончен
Round Two
подожди, посмотри ещеgithub.com/golang/protobuf
документ, в котором упоминаетсяv1.4.0
После версии код будет переданgoogle.golang.org/protobuf
Обслуживание репозитория, похоже, что Google получит все пакеты pb под свою организацию.
Тогда я просто положилgrpc
Инструмент генерации также заменен прошлым!
GO111MODULE=on go get -u google.golang.org/protobuf/cmd/protoc-gen-go@v1.21.0
сгенерировать код снова
Новый инструмент автоматически предлагает добавить в файл proto:
option go_package = ".;helloworld";
на самом деле не удалось. . . намекать:
--go_out: protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC
Это новый флаг, попробуйте:
protoc --go-grpc_out=. helloworld.proto
Что? +1 за провал. . .
protoc-gen-go-grpc: program not found or is not executable
Please specify a program using absolute path or make sure the program is available in your PATH system variable
--go-grpc_out: protoc-gen-go-grpc: Plugin failed with status code 1.
protoc-gen-go-grpc
Это новый инструмент?
Искал, действительно есть этот инструмент, говорят, что новая версия будет использовать его для генерацииgrpc
, в основном для лучшей поддержкиprotobuf reflection
Скажи это здесь:
прото-файл
service
Необходимостьgrpc
изplugin
Чтобы сгенерировать соответствующий pb-код Таким образом, у устаревших инструментов есть параметры--go_out=plugins=grpc:
Попробуйте установить:
GO111MODULE=on go get google.golang.org/protobuf/cmd/protoc-gen-go-grpc
Неудача +2. . .
go get google.golang.org/protobuf/cmd/protoc-gen-go-grpc: module google.golang.org/protobuf@upgrade found (v1.21.0), but does not contain package google.golang.org/protobuf/cmd/protoc-gen-go-grpc
goDoc имеетprotoc-gen-go-grpc,RepoНет, что это за операция?
Думаю, с этой проблемой должен столкнуться кто-то, и я нашел проблему:plugins are not supported:grpc
это былоgoogle.golang.org/protobuf
Он был выпущен первым, и он также содержит новую версиюprotoc-gen-go
,
Просто больше не поддерживаетсяgrpc
для генерации требуется другой инструментprotoc-gen-go-grpc
Однако он не был выпущен и до сих порReviewсередина. . . (Конечно, на данный момент это не будет стабильной версией)
Однако чиновник также сказал, что старую сумку все еще можно использовать.github.com/golang/protobuf
изprotoc-gen-go-grpc
создание инструментаgrpc
код
из-за старой сумки
protoc-gen-go-grpc
Вы все еще можете использовать новую сумкуprotoc-gen-go-grpc
Сгенерируйте код grpc вgengogrpc
, Видетьcomment
Round Three
Что ж, тогда просто обновите protobuf, вызываемый в коде, доgoogle.golang.org/protobuf@v1.21.0
, инструмент генерации кода по-прежнему использует старую версиюgithub.com/golang/protobuf/protoc-gen-go@v1.4.0
Бар
Создайте файл pb снова, и, наконец, нет проблем, наконец-то мир
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
Просто смотреть на сгенерированный код по-прежнему нужноimport
старая сумкаgithub.com/golang/protobuf
, это всегда странно
После обновления это зависит от двухprotobuf
Мешок. . .
Напоследок всем советую не торопиться, просто подождать и обновиться.
(Кроме того, ничего не нужно делать, чтобы перейти на новый пакет!)
Конечно, критическое изменение protobuf на этот раз по-прежнему имеет большое значение.Он не только делает отражение protobuf функцией первого уровня pb, но также предоставляет множество инструментов обработки.Подробности см. ниже:v1.21.0-release
Первый публичный аккаунт статьи: newbmiao
Рекомендуемое чтение:Серия Dig101-Go