#c #sockets #connection-pooling
#c #сокеты #объединение в пул соединений
Вопрос:
Я пишу библиотеку базы данных, которая должна будет разумно поддерживать тайм-ауты. Теперь, когда я смотрю на объединение в пул соединений, меня особенно беспокоит следующий сценарий:
- Отправить запрос #1
- Время ожидания истекло через n секунд.
- Отправить запрос #2
- Получение ответа на запрос # 1
Четвертый шаг может произойти, потому что запросы не помечены идентификатором запроса: все, что я знаю, это то, что я получил ответ, и я не знаю, какому запросу он принадлежит. Можно было бы возразить, что это представляет собой ошибку в протоколе, но это зависит не от меня.
Перед отправкой запроса № 2, что я должен сделать с сокетом, чтобы избежать такого позднего ответа? Это единственный правильный способ shutdown()
close()
и повторно connect()
?
Комментарии:
1. Как насчет добавления константы в select всех запросов, чтобы ваша библиотека могла определить, для какого запроса предназначен ответ?
2. Это отличная идея, но, к сожалению, не очень хорошая для библиотеки. Возможно, через плагин…
Ответ №1:
Я боюсь, что это единственный безопасный способ управлять вашим соединением, потому что нет другого способа получить однозначный ответ между вопросом и ответом по TCP. Похоже, между ними отсутствует какая-то функция отмены.
Эта ссылка дает больше информации: http://www.ssfnet.org/Exchange/tcp/tcpTutorialNotes.html
Комментарии:
1. В свою очередь, это потому, что TCP ничего не знает о ваших так называемых «запросах», «ответах» или «отменах». Подключенный сокет — это всего лишь две однонаправленные трубки для байтов (Тед Стивенс был прав). Если один конец записывает материал, а поток не поднимается, тогда другой конец может его прочитать. Итак, определение того, для какого «запроса» предназначен этот «ответ», является проблемой уровня приложения. Либо он встроен в протокол, который определяет запрос / ответ, либо он не существует.
2. Я имею в виду, я знаю. 🙂 Но у TCP есть порядковые номера, поэтому я надеялся, что есть какой-то трюк, который я мог бы использовать.
3. @Andres: к сожалению, порядковые номера просто позволяют уровню TCP собирать поток — нечего сказать, сколько времени прошло между конкретными байтами в противоположных направлениях. Помните, что только потому
n
, что с момента отправки первого запроса прошло несколько секунд, это не означаетn
, что с момента его прочтения на другом конце прошло несколько секунд. Таким образом, другой конец, возможно, отправил этот ответ до истечения времени ожидания от своего POV, но он прибыл к вам после истечения времени ожидания от вашего POV. Одни только тайм-ауты могут работать с надежным, синхронизированным по времени соединением, которым TCP не является.