Skip to content

Таймауты #29

Open
ivanych opened this issue Aug 14, 2018 · 11 comments
Open

Таймауты #29

ivanych opened this issue Aug 14, 2018 · 11 comments
Labels
backlog bug Something isn't working prio5 teamE Tarantool Ecosystem Team

Comments

@ivanych
Copy link

ivanych commented Aug 14, 2018

Пытаюсь установить таймаут на подключение к Тарантулу. Для имитации аварии замедлил Тарантул по максимуму (урезал ему процессор и память, чтобы он еле шевелился).

Использую DR::Tarantool::MsgPack::SyncClient.

Передаю ему таймауты так:

my $client = DR::Tarantool::MsgPack::SyncClient->connect(
        host                    => $host,
        port                     => $port,
        connect_timeout => 1,
        request_timeout => 1,
    );

Я ожидаю, что если соединение не установится за 1 секунду, то процесс прервется и вылетит какой-нибудь эксепшен.

Но процесс не прерывается. Все зависает на строке my ($self) = $cv->recv; в функции connect модуля DR::Tarantool::MsgPack::SyncClient. Определил просто понаставив варнингов в разных местах. До этой функции доходит и на ней всё останавливается и дальше ничего не происходит.

Это я что-то не так делаю? Может быть, SyncClient вообще не умеет работать с таймаутами?

@limpasha
Copy link

На самом деле, SyncClient почти не тестируется. Предполагается, что он является некой built-in оберткой над ядром -- AsyncClient'ом, который является основным.

Так что сразу не подскажу по SyncClient'у, нужно посмотреть. Точно должен работать AsyncClient, там при connect_timeout вызывается переданный callback с ошибкой. В основном сейчас пока пишут такую обертку вида my $cv = AE::cv; DR::Tarantool::MsgPack::AsyncClient->connect(); $cv->recv в своем приложении сами.

@ivanych
Copy link
Author

ivanych commented Aug 14, 2018

Я докопал до следующего:

В функции DR::Tarantool::AEConnection::connect вызывается функция AnyEvent::Socket::tcp_connect. Она выполняется успешно, потому что, насколько я понимаю, тормозящий Тарантул тут не играет роли, тут всё происходит на уровне TCP, а там всё нормально. После этого вызывается коллбэк фунции AnyEvent::Socket::tcp_connect. В коллбэке делается $self->{guard} = {}; и всё, привет - таймер для connect_timeout исчезает.

Но затем вызывается что-то еще, где уже важен тормозящий Тарантул. Но таймаута для connect_timeout УЖЕ нет, а таймаут для request_timeout на это что-то похоже ЕЩЁ не действует.

@ivanych
Copy link
Author

ivanych commented Aug 14, 2018

Похоже, что дело в вызове функции DR::Tarantool::AEConnection::read_while с параметром "handshake".

На этом этапе (уже после tcp_connect) никаких таймеров с таймаутами не установлено. Тарантул не отвечает - функция ждет бесконечно, всё висит.

Но всё это происходит внутри connect, и, вроде бы, должно управляться таймаутом connect_timeout.

Подозреваю, что это баг. Можете проверить?

@ivanych
Copy link
Author

ivanych commented Aug 17, 2018

Ребята?

@limpasha
Copy link

Сорри за задержку. Я посмотрю.

@bigbes
Copy link

bigbes commented Aug 17, 2018

В принципе во всех коннекторах это реализовано так, что максимальный таймаут на соединение это коннект + рид, именно из-за природы операции коннекта (для тарантула):

  • системный коннект
  • рид хендшейка
  • авторизация (если нужна)
  • получение схемы (двумя запросами)

Так что я не уверен, что это стоит решать единым таймаутом на коннект.

@ivanych
Copy link
Author

ivanych commented Aug 17, 2018

Эм... не совсем понял. Вы подтверждаете, что хендшейк не контролируется таймаутом, но полагаете, что так и нужно?

Но это же довольно-таки опасно получается. Это приведет к зависанию приложения без каких-либо варнингов. Я чего копаться-то полез - у меня как-раз так и вышло, всё висело и при этом ни на что не жаловалось.

Всё это в обязательном порядке придется накрывать самодельным таймаутом. А раз обязательно - то прям просится сделать это в самом модуле...

@bigbes
Copy link

bigbes commented Aug 17, 2018

Я утверждаю что:

  • handshake read должен контролироваться таймаутом на request_timeout
  • соединение (сам вызов сокетный) должен ограничиваться с помощью connect_timeout
  • все запросы/ответы должны контролироваться с помощью request_timeout

Смысла всё это подпихивать в connect_timeout нет, ибо выходит что максимальное время вполне измеримо. Вот это я утверждаю.

То что handshake read висит бесконечно - нет, я не утверждаю что так должно быть.

@ivanych
Copy link
Author

ivanych commented Aug 17, 2018

Хорошо, пусть хендшейк контролируется request_timeout. Но дело-то в том, что сейчас он не контролируется никаким таймаутом.

@limpasha
Copy link

Да, всё верно, @ivanych, на вычитывание handshake-данных таймаута нет :( Спасибо. Постараюсь поскорее пофиксить.

@ivanych
Copy link
Author

ivanych commented Nov 1, 2019

@limpasha Удалось пофиксить?

@Totktonada Totktonada added the bug Something isn't working label Jul 9, 2020
@Totktonada Totktonada added backlog prio5 teamE Tarantool Ecosystem Team labels Dec 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
backlog bug Something isn't working prio5 teamE Tarantool Ecosystem Team
Projects
None yet
Development

No branches or pull requests

4 participants