Вспомните прекрасное путешествие по обновлению пакета go-protobuf

Go
Вспомните прекрасное путешествие по обновлению пакета go-protobuf

Сегодня поговорим о недавно обновленном ходу.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.

心塞x1

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

心塞x2

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 снова, и, наконец, нет проблем, наконец-то мир

peace

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

欢迎关注,获取及时更新内容