#ruby-on-rails #ruby #http #net-http
#ruby-on-rails #ruby #http #net-http
Вопрос:
Допустим, что я вызываю следующий код изнутри цикла с 1-секундной задержкой между каждой итерацией, а URL-это API. Как мне убедиться, что Net:: HTTP использует один и тот же сеанс API для всех вызовов? Я знаю, что в документации говорится, что Net::HTTP.new попытается повторно использовать одно и то же соединение. Но как мне это проверить? Есть ли идентификатор сеанса, который я могу извлечь из Net:: HTTP?
request = Net::HTTP::Put.new(url)
url = URI(url)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request["Accept"] = 'application/json'
request["Content-Type"] = 'application/json'
request["Authorization"] = @auth_key
request["cache-control"] = 'no-cache'
request.body = request_body.to_json if request_body
response = http.request(request)
Ответ №1:
дважды проверьте следующее на версии ruby, на которой вы работаете
Во-первых, я не думаю, что есть какой-либо идентификатор сеанса, из того, что я вижу, который был бы весьма полезной функцией. Далее, просматривая исходный код, мы видим настройку переменной в lib/net/http.rb
в таких методах, как:
def do_finish
@started = false
@socket.close if @socket
@socket = nil
end
# Returns true if the HTTP session has been started.
def started?
@started
end
# Finishes the HTTP session and closes the TCP connection.
# Raises IOError if the session has not been started.
def finish
raise IOError, 'HTTP session not yet started' unless started?
do_finish
end
Где do_finish устанавливает переменную экземпляра @socket
в nil и @socket
используется в качестве экземпляра bufferedIO для запуска HTTP-запросов через
Итак, я бы написал метод переопределения для finish
метода и поднимал предупреждение, когда он вызывает do_finish
. .
Просмотр комментариев start
— самый безопасный вариант использования одного и того же сеанса, поэтому вы можете использовать начальный блок и сравнить, что идентификатор переменной экземпляра не меняется
Net::HTTP.start(url) do |http|
before = http.instance_variable_get(:@socket)
loop do
instance_var = http.instance_variable_get(:@socket)
break unless before == instance_var
end
end
Комментарии:
1. кажется хорошим решением. Как вы думаете, это могло бы сработать и в случае, если прокси-сервер не может поддерживать соединение? В этом случае, возможно, сервер все еще может поддерживать TCP-соединение, что означает, что он не вызывает
finish
, и может открыть другое соединение для ответа на HTTP-запрос, поступающий от прокси, который запускает новое соединение. Проблема в том, что с HTTP 1/1 соединение поддерживается активным по соображениям производительности, нет гарантий, что это всегда возможно.