Служба с INDY виснет при исчезновении интернета.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Служба с INDY виснет при исчезновении интернета.

Сообщение jsa »

Всем привет.

Имеется простой телеграм-бот. Служба получает входящие сообщения исходящим методом getUpdates "длинным запросом" Long polling по 7 сек.
Длинный запрос getUpdates запускается по таймеру раз в 500мс если входящие пустые, или сразу после обработки входящих сообщений.

Телеграм библиотеки не используются никакие. Все обычными HTTP запросами через indy компоненту TidHTTP
Стабильный эффект наблюдаю.
Если пропадает инет (свет в доме выключен, провода перетыкаю, и т.д.) то служба виснет.
В коде у меня всё, что только можно обернуто в try except но в логах нет никаких отметок.

Я так понимаю есть варианта возникновения ситуации.
1. между длинными запросами.
2. разрыв во время выполнения длинного запроса

В первом случае можно сначала выполнить пинг запрос HEAD для проверки доступности сервера.
А вот во втором случае не понятно, что делать.

Посоветуйте пожалуйста, что можно сделать?
Что угодно, но без существенной пересборки проекта.
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

На вскидку.
1. Включить TCP KeepAlive

Код: Выделить всё

// В OnConnected
 with TIdHTTP(Sender) do
    if Assigned(Socket) then
      Socket.SetKeepAliveValues(True, 60000, 5000);
    
По идее, если будет разрыв соединения, то ОС сама разорвёт сокет и TIdHTTP выбросит исключение вместо зависания.


2. Попробовать замерять время. Если запрос не вернулся за заданное время - уничтожать и создавать TIdHTTP заново.
Аватара пользователя
Sharfik
энтузиаст
Сообщения: 836
Зарегистрирован: 20.07.2013 01:04:30

Сообщение Sharfik »

Телеграмм боты это зло, вообще любые боты это зло. И очень правильно что все зависает ведь ОС пытается защитить людей от ереси. :!:
Компьютер был придуман в помощь человеку, а не для порчи настроения ботами.

Что могло быть:
1. Запись логов при синхронизации в клин встала
2. Сменился IP и север неправильно обрабатывает ситуацию
Короче ставить запись логов и смотреть.
Alex2013
долгожитель
Сообщения: 3211
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Предложения в порядке "мозгового штурма ":
1 Простые "try except" помогают невсегда (мене в похожей ситуации помог DeepSeek предложив более жесткий контроль компонента TlistView, возможно что-то похожие поможет и в этом случае )
2 Возможно нужно принудительно установить тайм-аут в TIdHTTP.
3 Еще можно "обернуть" проблемный код потоком и проверять тайм-аут самостоятельно.
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

WAYFARER писал(а):Включить TCP KeepAlive
По умолчанию в IdHttp он включен.
IdHTTP.Socket.SetKeepAliveValues нет такой процедуры в TIdHTTP

Про KeepAlive посмотрел, и так понял это нужно чтобы держать сокет открытым для экономии времени на соединение.
Но у меня на каждой итерации создается TIdHttp.Create(nil) отрабатывает запрос и удаляется IdHttp.Free

Не понимаю как проблеме поможет keep-alive?
В компонентах Indy TIdHTTP (на стороне клиента) и TIdHTTPServer (на стороне сервера) реализована концепция HTTP Keep-Alive, позволяющая выполнять несколько запросов и ответов по одному TCP-соединению, что повышает производительность за счет снижения затрат на установление новых соединений для каждого запроса.
Добавлено спустя 42 минуты 17 секунд:
---------
Мда сказочно я затупил.
Думал таймауты настроены, но оказалось нет.
Теперь прописал

Код: Выделить всё

IdHTTP_post.ConnectTimeout:=1000;
IdHTTP_post.ReadTimeout:={времядлинногозапроса+1}*1000; 
Проверил вынув инет-кабель на 5 минут/
В try except стала происходить отработка и в логах потеря соединения нормально отобразилась. А после появления коннекта нормально продолжилась работа.

Всем спасибо.
Вопрос закрыт.
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 564
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

jsa, нет. HTTP Keep Alive не есть TCP KeepAlive.
TCP KeepAlive реализован на уровне ядра ОС и его цель в проверки живо ли соединение. Как писал выше оно надо что бы получить исключение вместо зависания.
jsa писал(а):IdHTTP.Socket.SetKeepAliveValues нет такой процедуры в TIdHTTP
Версия Indy какая? Сейчас попробую пример накидать

Добавлено спустя 5 минут 46 секунд:
jsa писал(а):IdHTTP.Socket.SetKeepAliveValues нет такой процедуры в TIdHTTP
потому что я перепутал, оно в IOHandler...
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

WAYFARER писал(а):Версия Indy какая?
10.6.3.11
WAYFARER писал(а):Сейчас попробую пример накидать
Спасибо. Вроде как решил проблему.
Ответить