最近开始使用阿里云的日志服务来上传客户端的日志。需要发送pb格式日志压缩数据。客户端使用lua脚本,pb模块使用protoc-gen-lua。
在测试写入接口的时候,有时候返回成功,有时候返回"fail to parse protobuf"。
查了一下发现protoc-gen-lua的序列化的结果是不稳定的。
protobuf.lua中_internal_serialize函数实现,ListFields方法遍历是无序的,会导致结果不稳定,阿里云平台无法反序列化。
local _internal_serialize = function(self, write_bytes)
for field_descriptor, field_value in message_meta._member.ListFields(self) do
field_descriptor._encoder(write_bytes, field_value)
end
end
改动:根据field的key的index排序,再进行遍历。这样输出的结果是稳定的。
local _internal_serialize = function(self, write_bytes)
local field_list = {}
for k, v in pairs(self._fields) do
field_list[k.index + 1] = k
end
local n = table.maxn(field_list)
for i = 1, n do
local descriptor = field_list[i]
if descriptor then
value = self._fields[descriptor]
if _IsPresent(descriptor, value) then
descriptor._encoder(write_bytes, value)
end
end
end
end