Skip to content

Commit c166792

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 c166792

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-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.lua

+2
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ local function select_on_storage(space_name, index_id, conditions, opts)
112112
-- getting tuples with user defined fields (if `fields` option is specified)
113113
-- and fields that are needed for comparison on router (primary key + scan key)
114114
local filtered_tuples = schema.filter_tuples_fields(resp.tuples, opts.field_names)
115+
require('log').info("filtered_tuple=%s, #filtered_tuples=%d", require('json').encode(filtered_tuples), #filtered_tuples)
116+
assert(#filtered_tuples >= 0)
115117

116118
local result = {cursor, filtered_tuples}
117119

crud/select/merger.lua

+22-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,23 @@ 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+
--{48: [cursor, [tuple_1, tuple_2, ...]], 96: {id: tuple_format}}
83+
-- [cursor, [tuple_1, tuple_2, ...]] (value)
84+
data[0] = data[0] + 1
85+
end
86+
87+
return decode_response_array_header()
88+
end
89+
8390
local function decode_metainfo(buf)
8491
-- Skip an array around a call return values.
8592
buf.rpos = decode_response_headers(buf)
@@ -192,7 +199,8 @@ local function new(vshard_router, replicasets, space, index_id, func_name, func_
192199
for _, replicaset in pairs(replicasets) do
193200
-- Perform a request.
194201
local buf = buffer.ibuf()
195-
local net_box_opts = {is_async = true, buffer = buf, skip_header = false}
202+
local net_box_opts = {is_async = true, buffer = buf,
203+
skip_header = utils.tarantool_supports_netbox_skip_header_option()}
196204
local future = replicaset[vshard_call_name](replicaset, func_name, func_args,
197205
net_box_opts)
198206

@@ -249,7 +257,8 @@ local function new_readview(vshard_router, replicasets, readview_uuid, space, in
249257
if replica_uuid == value.uuid then
250258
-- Perform a request.
251259
local buf = buffer.ibuf()
252-
local net_box_opts = {is_async = true, buffer = buf, skip_header = false}
260+
local net_box_opts = {is_async = true, buffer = buf,
261+
skip_header = utils.tarantool_supports_netbox_skip_header_option()}
253262
func_args[4].readview_id = value.id
254263
local future = replica.conn:call(func_name, func_args, net_box_opts)
255264

0 commit comments

Comments
 (0)