当前位置:网站首页>[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 .
边栏推荐
- 阿里云个人镜像仓库日常基本使用
- 12个MySQL慢查询的原因分析
- The postgraduate entrance examination in these areas is crazy! Which area has the largest number of candidates?
- When are global variables initialized before entering the main function?
- Gd32 USB composite device file descriptor
- windows系统下怎么安装mysql8.0数据库?(图文教程)
- SentinelResource注解详解
- JWT操作工具类分享
- C language 99 multiplication table
- On the origin of the dispute between the tradition and the future of database -- AWS series column
猜你喜欢

云计算技术的发展与芯片处理器的关系

基于SSH框架的学生信息管理系统

Leetcode question brushing: String 05 (Sword finger offer 58 - ii. left rotation string)

Establish a connection with MySQL

leetcode刷题:字符串02( 反转字符串II)

Leetcode question brushing: String 06 (implement strstr())

IDEA 报错:Process terminated【已解决】
![[Bayesian classification 4] Bayesian network](/img/5b/348e00c920028e33ca457196586d36.png)
[Bayesian classification 4] Bayesian network

这些地区考研太疯狂!哪个地区报考人数最多?

The postgraduate entrance examination in these areas is crazy! Which area has the largest number of candidates?
随机推荐
Gamefi active users, transaction volume, financing amount and new projects continue to decline. Can axie and stepn get rid of the death spiral? Where is the chain tour?
西瓜书重温(七): 贝叶斯分类器(手推+代码demo)
[Shandong University] information sharing for the first and second examinations of postgraduate entrance examination
孙老师版本JDBC(2022年6月12日21:34:25)
C primer plus learning notes - 3. Character IO (input / output)
开发者调查:Rust/PostgreSQL 最受喜爱,PHP 薪水偏低
MySQL - subquery usage
The postgraduate entrance examination in these areas is crazy! Which area has the largest number of candidates?
基于QT开发的线性代数初学者的矩阵计算器设计
Leetcode question brushing: String 02 (reverse string II)
【贝叶斯分类4】贝叶斯网
Sentinelresource annotation details
回首望月
Arduino uno + DS1302 uses 31 byte static RAM to store data and print through serial port
【贝叶斯分类3】半朴素贝叶斯分类器
手机股票注册开户有没有什么风险?安全吗?
Dynamic planning 111
BOM and DOM operations
Matrix calculator design for beginners of linear algebra based on Qt development
MySQL中存储过程的详细详解