Skip to content

Commit b7de7b2

Browse files
merger: use the skip_header option of the net.box connection's API
In scope of tarantool/tarantool#8147, a new context-dependent extension for box tuples, `MP_TUPLE`, is introduced, and the IPROTO data response is extended with a new `IPROTO_TUPLE_FORMATS` field with tuples formats necessary for decoding `MP_TUPLE` sent in the `IPROTO_DATA` field. If the tuple merger's buffer source is used, raw MsgPack is received (see also d18ad41). We expect the response to only contain an `IPROTO_DATA` field, so the occurrence of a new `IPROTO_TUPLE_FORMATS` field breaks this assumption. The `IPROTO_DATA` field is still decoded correctly, but the input buffer's position now points to the `IPROTO_TUPLE_FORMATS` field instead of the end of the response. Instead of handling the issue described above we decided to opt for a simpler solution, namely, using the `skip_header` option of the `net.box` connection's API, which returns only the `IPROTO_DATA` field's value, which is what we are looking for. This option is was introduced in tarantool/tarantool@1aaf637870 (2.2.0 release), but since the issue described above can only occur with the latest Tarantool version, we can safely fallback to manually decoding the `IPROTO_DATA` header on old Tarantool versions. Needed for tarantool/tarantool#8147
1 parent 2bfbbe5 commit b7de7b2

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

crud/common/utils.lua

+11
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,9 @@ local function determine_enabled_features()
639639
or is_version_in_range(major, minor, patch, suffix,
640640
1, 10, 8, nil,
641641
1, 10, math.huge, nil)
642+
643+
enabled_tarantool_features.netbox_skip_header_option = is_version_ge(major, minor, patch, suffix,
644+
2, 2, 0, nil)
642645
end
643646

644647
function utils.tarantool_supports_fieldpaths()
@@ -681,6 +684,14 @@ function utils.tarantool_supports_external_merger()
681684
return enabled_tarantool_features.external_merger
682685
end
683686

687+
function utils.tarantool_supports_netbox_skip_header_option()
688+
if enabled_tarantool_features.netbox_skip_header_option == nil then
689+
determine_enabled_features()
690+
end
691+
692+
return enabled_tarantool_features.netbox_skip_header_option
693+
end
694+
684695
local function add_nullable_fields_recursive(operations, operations_map, space_format, tuple, id)
685696
if id < 2 or tuple[id - 1] ~= box.NULL then
686697
return operations

crud/select/merger.lua

+21-13
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,7 @@ end
5858

5959
local data = ffi.new('const unsigned char *[1]')
6060

61-
local function decode_response_headers(buf)
62-
-- {48: [cursor, [tuple_1, tuple_2, ...]]} (exactly 1 pair of key-value)
63-
data[0] = buf.rpos
64-
65-
-- 48 (key)
66-
data[0] = data[0] + 1
67-
68-
-- [cursor, [tuple_1, tuple_2, ...]] (value)
69-
data[0] = data[0] + 1
70-
71-
-- Decode array header
61+
local function decode_response_array_header()
7262
local c = data[0][0]
7363
data[0] = data[0] + 1
7464
if c == 0xdc then
@@ -80,6 +70,22 @@ local function decode_response_headers(buf)
8070
return ffi.cast(char_ptr, data[0])
8171
end
8272

73+
local function decode_response_headers(buf)
74+
data[0] = buf.rpos
75+
76+
if not utils.tarantool_supports_netbox_skip_header_option() then
77+
-- {48: [cursor, [tuple_1, tuple_2, ...]]} (exactly 1 pair of key-value)
78+
79+
-- 48 (key)
80+
data[0] = data[0] + 1
81+
82+
-- [cursor, [tuple_1, tuple_2, ...]] (value)
83+
data[0] = data[0] + 1
84+
end
85+
86+
return decode_response_array_header()
87+
end
88+
8389
local function decode_metainfo(buf)
8490
-- Skip an array around a call return values.
8591
buf.rpos = decode_response_headers(buf)
@@ -192,7 +198,8 @@ local function new(vshard_router, replicasets, space, index_id, func_name, func_
192198
for _, replicaset in pairs(replicasets) do
193199
-- Perform a request.
194200
local buf = buffer.ibuf()
195-
local net_box_opts = {is_async = true, buffer = buf, skip_header = false}
201+
local net_box_opts = {is_async = true, buffer = buf,
202+
skip_header = utils.tarantool_supports_netbox_skip_header_option()}
196203
local future = replicaset[vshard_call_name](replicaset, func_name, func_args,
197204
net_box_opts)
198205

@@ -249,7 +256,8 @@ local function new_readview(vshard_router, replicasets, readview_uuid, space, in
249256
if replica_uuid == value.uuid then
250257
-- Perform a request.
251258
local buf = buffer.ibuf()
252-
local net_box_opts = {is_async = true, buffer = buf, skip_header = false}
259+
local net_box_opts = {is_async = true, buffer = buf,
260+
skip_header = utils.tarantool_supports_netbox_skip_header_option()}
253261
func_args[4].readview_id = value.id
254262
local future = replica.conn:call(func_name, func_args, net_box_opts)
255263

0 commit comments

Comments
 (0)