SSLSocket не может выполнить запрос без небольшого сна перед закрытием сокета

#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
 

Спасибо!