#ruby #sockets #openssl
Вопрос:
Контекст:
У нас есть веб-приложение rails, которое взаимодействует с другим приложением rails. Чтобы ускорить наши запросы и сэкономить драгоценное время для процесса с низким приоритетом, мы решили использовать сокеты для запуска запросов, не дожидаясь ответа от внешнего приложения.
Проблема:
При использовании OpenSSL::SSL::SSLSocket для запуска запроса мы заметили интересную проблему. Со 100% уверенностью можно сказать, что запрос создан правильно, многие запросы были потеряны и не попали во внешнее приложение. На самом деле подавляющее большинство из них так и не были получены.
Решение:
Добавление короткого сна после записи и перед закрытием сокета устранило проблему, и запросы были успешно запущены и получены внешним приложением.
Вопрос:
Такое поведение сокетов является неожиданным, и я ожидал бы, что вызов закрытия будет сброшен и закроет поток, гарантирующий выполнение запроса. Это ошибка в библиотеке?
Код:
def fire_and_forget_post
tcp_socket = Socket.tcp(@uri.host, @uri.port, connect_timeout: 5)
context = OpenSSL::SSL::SSLContext.new
context.set_params(verify_mode: OpenSSL::SSL::VERIFY_PEER)
@ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, context).tap do |socket|
socket.sync_close = true
socket.hostname = @uri.hostname
socket.connect
end
@ssl_socket.syswrite socket_request
sleep 0.004 # Without this sleep the request is not received
ensure
@ssl_socket.sysclose
end
Спасибо!