Connection hangs if Tarantool's `readahead` limit is reached
Closed this issue · 0 comments
CuriousGeorgiy commented
Consider the following server setup and connector usage:
os.execute('rm -rf *.snap *.xlog *.vylog 512')
console = require('console')
box.cfg{listen = 3301, memtx_memory = 1024*1024*1024, wal_mode = 'none', readahead = 65536}
box.once('bootstrap', function()
local s = box.schema.space.create('tester', {if_not_exists = true})
s:format({{name = 'id', type = 'unsigned'}})
s:create_index('primary', {type = 'tree', parts = {'id'}, if_not_exists = true})
box.schema.user.grant('guest', 'read,write,execute', 'universe', nil, {if_not_exists = true})
end)
console.start()
os.exit()
#include <array>
#include <random>
#include <limits>
#include <vector>
#include "src/Client/Connector.hpp"
#include "src/Buffer/Buffer.hpp"
const char *address = "127.0.0.1";
int port = 3301;
using Buf_t = tnt::Buffer<16 * 1024>;
using Net_t = LibevNetProvider<Buf_t, DefaultStream>;
constexpr std::size_t field_count = 1000;
constexpr std::size_t reqs_count = 1000;
constexpr std::uint32_t space_id = 512;
int
main()
{
Connector<Buf_t, Net_t> client;
Connection<Buf_t, Net_t> conn(client);
int rc = client.connect(conn, {
.address = address,
.service = std::to_string(port),
});
if (rc != 0) {
std::cerr << conn.getError().msg << std::endl;
return EXIT_FAILURE;
}
rid_t ping = conn.ping();
if (client.wait(conn, ping) != 0) {
std::cerr << conn.getError().msg << std::endl;
return EXIT_FAILURE;
}
std::optional<Response<Buf_t>> response = conn.getResponse(ping);
assert(response != std::nullopt);
std::default_random_engine rng{std::random_device()()};
std::uniform_int_distribution<std::uint64_t> values(0, std::numeric_limits<uint64_t>::max());
std::array<std::vector<std::uint64_t>, reqs_count> reqs;
for (std::size_t i = 0; i < reqs_count; ++i) {
reqs[i].reserve(field_count);
reqs[i].push_back(i + 1);
for (std::size_t k = 1; k < field_count; ++k) {
reqs[i].push_back(values(rng));
}
}
std::vector<rid_t> futures(reqs_count);
for (std::size_t i = 0; i < reqs_count; ++i) {
futures[i] = conn.space[space_id].replace(reqs[i]);
}
client.waitAll(conn, futures);
for (const auto &future : futures) {
assert(conn.futureIsReady(future));
response = conn.getResponse(future);
assert(response != std::nullopt);
}
client.close(conn);
}
Actual behavior
The script hangs.
Expected behavior
The script successfully executes.