Как мне убедиться, что я использую один и тот же сеанс для нескольких HTTP-вызовов?

#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 соединение поддерживается активным по соображениям производительности, нет гарантий, что это всегда возможно.