Home > Software design >  How to safely recycle protobuf objects in golang
How to safely recycle protobuf objects in golang

Time:01-10

I want to recycle the message object of protobuf to reduce GC consumption at runtime,but I'm not sure whether it's safe.The sample code for testing is as follows:

test.proto

message Hello{
  uint32  id   = 1;
}

test.pb.go

type Hello struct {
    state         protoimpl.MessageState
    sizeCache     protoimpl.SizeCache
    unknownFields protoimpl.UnknownFields

    ID  uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
}

func (x *Hello) Reset() {
    *x = Hello{}
    if protoimpl.UnsafeEnabled {
        mi := &file_proto_login_api_login_proto_msgTypes[0]
        ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
        ms.StoreMessageInfo(mi)
    }
}
// other codes

main.go

func main() {
    // Disable GC to test re-acquire the same data
    gc := debug.SetGCPercent(-1)

    // As a protobuf object pool
    cache := sync.Pool{New: func() interface{} { return &test.Hello{} }}
    
    // Take out an object and use it
    m1 := cache.Get().(*test.Hello)
    m1.ID = 999
    fmt.Println(&m1.ID) // print 999

    // Empty the data and put it back into the object pool
    m1.Reset()
    cache.Put(m1)

    // Take out an object again and use it
    m2 := cache.Get().(*test.Hello)
    fmt.Println(&m2.ID) // print 0

    debug.SetGCPercent(gc)
}

CodePudding user response:

The code you show is safe. Pooling like this becomes "unsafe" when references to objects are held after they are put into the pool. You risk race conditions or strange bugs. So it also depends on the code that uses your objects.

The protocol buffers library and gRPC libraries don't hold on to references to protobuf objects, as far as I know. Doing so would break a lot of code since such libraries have no way of knowing when it would be safe to reuse.

So as long as you make sure that your own code doesn't use objects after they are put in the pool, you should be good.

  •  Tags:  
  • Related