当前位置:网站首页>[protobuf] some pits brought by protobuf upgrade
[protobuf] some pits brought by protobuf upgrade
2022-06-26 20:57:00 【Manon impression】
Some time ago, the company relied on github.com/golang/protobuf Version from v1.3.3 Upgrade to v1.4.2, This article records some problems encountered during the upgrade process .
Google Yes Go Of protobuf The bottom layer of the library has been greatly improved , The package path of the new version is transferred to google.golang.org/protobuf.
meanwhile , These improvements have also been brought into github.com/golang/protobuf: from v1.4 Since version ,github.com/golang/protobuf Will be in google.golang.org/protobuf On the basis of , But it will ensure that the interface is compatible , This also indicates the current dependency github.com/golang/protobuf The project can be upgraded directly , There is no need to change the upper code .
However , New version of the protobuf-gen-go Used google.golang.org/protobuf/protoreflect, Compile the message The structure is completely different , This has brought some trouble to our upgrade work .
1. Right in code XXX_Unmarshal Direct call to
The original protoc-gen-go Will expose a XXX_Unmarshal Interface , Used in proto.Unmarshal Called when , So some colleagues choose to call directly message.XXX_Unmarshal Method . New version of the proto adopt ProtoReflect Interface exposed message Internal information , compile pb.go Time is gone XXX_Unmarshal Method , So it will cause compilation errors message.XXX_Unmarshal undefined.
The solution is simple : change to the use of sth. proto.Unmarshal that will do .
2. Changes in the internal structure of the structure lead to test errors
For the same message, The structure of the compiled structure of the old version is as follows :
type HealthCheckResponse struct {
Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=liulishuo.common.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{
} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
The compiled structure of the new version is as follows :
type HealthCheckResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=liulishuo.common.health.v1.HealthCheckResponse_ServingStatus" json:"status,omitempty"`
}
You can see , Three non exported fields have been added in the new version , These three fields bring some trouble to our test code .
- cmp.Equal when panic
Our tests usedgithub.com/google/go-cmp/cmp.EqualCome on proto Compare the structure , The non exported fields in the structure will makecmp.Equalandcmp.Diffpanic:
panic: cannot handle unexported field at {
*pkg.SomeRequest}.state:
".../services_go_proto".SomeRequest
consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported [recovered]
go-cmp The recommended way is to use IgnoreUnexported, But this method needs to pass all types that need to be ignored , For those with multiple levels of nesting message Very unfriendly .
After a search , Find out protocmp.Transform I can take all of them protobuf message Convert to custom map[string]interface{} Compare , So we can use Transform() To solve the problem :
import "google.golang.org/protobuf/testing/protocmp"
// ...
opt := protocomp.Trnasform()
if !cmp.Equal(exp, got, opt) {
t.Error(exp, got, opt)
}
- assert Stuck and full of memory
Compared with the above problem , The following question is even more strange : Usegithub.com/stretchr/testify/assert.EqualCompare some special proto message It will get stuck when , At the same time, memory usage will skyrocket .
Try to use pprof sampling , Extracted CPU And the heap sample graph looks like this :


You can see spew.Dump There is infinite recursion in , This leads to program sticking and persistent memory allocation .
Then we found it testify Of issue, Several bypass schemes have been proposed in relevant comments , However, this problem has not been solved .
There are two personally recommended solutions :
- Use
marshalTextString()take message convert to proto text, Then compare ; - Use
cmp.Equal, combinationprotocmp.Transform.
3. lint Report errors copylocks
After processing the business code processing test , After processing the test code, there are lint To deal with .
After upgrading our project ,go vet Will be submitted to the copylocks error :assignment copies lock value to got: .../message_go_protos.Message contains google.golang.org/protobuf/internal/impl.MessageState contains sync.Mutex
The solution is simple : Will all proto message Change to pointer passing .
边栏推荐
- Leetcode question brushing: String 05 (Sword finger offer 58 - ii. left rotation string)
- Review of watermelon book (VII): Bayesian classifier (manual push + code demo)
- Garbage collection mechanism of browser
- C primer plus学习笔记 —— 3、字符的IO(输入/输出)
- [Shandong University] information sharing for the first and second examinations of postgraduate entrance examination
- 30. concatenate substrings of all words
- 郭明錤:苹果 AR / MR 头显是其有史以来设计最复杂的产品,将于 2023 年 1 月发布
- Super VRT
- 记录一次Redis大Key的排查
- leetcode刷题:字符串04(颠倒字符串中的单词)
猜你喜欢

Detailed explanation of retrospective thinking

The relationship between the development of cloud computing technology and chip processor

Two methods of QT to realize timer
![[Shandong University] information sharing for the first and second examinations of postgraduate entrance examination](/img/f9/68b5b5ce21f4f851439fa061b477c9.jpg)
[Shandong University] information sharing for the first and second examinations of postgraduate entrance examination

Comment installer la base de données MySQL 8.0 sous Windows? (tutoriel graphique)
![[serial] shuotou O & M monitoring system 01 overview of monitoring system](/img/b2/bc75a4d0c8d98056d93ba99b3e6193.png)
[serial] shuotou O & M monitoring system 01 overview of monitoring system

记录一次Redis大Key的排查

Leetcode question brushing: String 03 (Sword finger offer 05. replace space)

Disruptor本地线程队列_使用transProcessor处理器和WorkPool两种方式进行消费对比---线程间通信工作笔记005

Keep alive cache component in Vue
随机推荐
C语言 文件光标 fseek
Sentinelresource annotation details
浏览器事件循环
【连载】说透运维监控系统01-监控系统概述
郭明錤:苹果 AR / MR 头显是其有史以来设计最复杂的产品,将于 2023 年 1 月发布
BOM and DOM operations
基于QT开发的线性代数初学者的矩阵计算器设计
西瓜书重温(七): 贝叶斯分类器(手推+代码demo)
动态规划111
Can I open an account online? Is it safe?
Super VRT
0 basic C language (1)
Dynamic parameter association using postman
Review of watermelon book (VII): Bayesian classifier (manual push + code demo)
[most detailed] latest and complete redis interview (42 tracks)
[Bayesian classification 3] semi naive Bayesian classifier
C: 反转链表
Flutter TextField详解
Developer survey: rust/postgresql is the most popular, and PHP salary is low
515. 在每个树行中找最大值