HTTPoison вручную закрыть соединение - PullRequest
1 голос
/ 18 марта 2019

Это очень простой модуль, который постоянно проверяет IP-адрес запрашивающей стороны. Я использую прокси-серверы обратного соединения, что означает, что он получает новый IP-адрес при каждом запросе http.

defmodule Test do
  def go() do
    Enum.each(1..1, fn x ->
    Task.Supervisor.async_nolink(Scraper.TaskSupervisor, fn ->
      r = HTTPoison.get("https://api.ipify.org?format=json", [],
        [timeout: 10_000, recv_timeout: 10_000, proxy: "ip:port", ssl: [{:versions, [:'tlsv1.2']}]])

      case r do

        {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
          IO.inspect body |> Jason.decode
          :timer.sleep(1000)
          go()
      end
    end)
    end)

  end
end
Test.go()
:timer.sleep(2000000)

Проблема? HTTPoison (hackney) не освобождает соединение, пока процесс активен, поэтому IP всегда одинаков. Как бы я вручную закрыл соединение внутри:

{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
          IO.inspect body |> Jason.decode

Ответы [ 2 ]

1 голос
/ 18 марта 2019

Оказалось, что самое простое решение - установить pool: false, весь запрос выглядит так:

HTTPoison.get(url, [], [
  timeout: 5_000,
  recv_timeout: 5_000,
  proxy: proxy,
  hackney: [pool: false],
  ssl: [{:versions, [:'tlsv1.2']}]
])
0 голосов
/ 18 марта 2019

Из HTTPoison README:

Обычно hackney открывает и закрывает соединения по требованию , но также создает пул по умолчанию соединений, которые повторно используются для запросов к тому же хосту. Если соединение и хост поддерживают keepalive, соединение остается открытым до тех пор, пока оно не будет явно закрыто.

HTTPoison не экспортирует close для основного сокета, и для него существует открытый выпуск с 2017 года.

Между тем, вы можете позвонить hackney_pool:stop_pool(:default). Это, очевидно, не оптимальное решение в любом случае, и оно имеет огромные накладные расходы. Поэтому я бы посоветовал предоставить запрос на HTTPoison, включающий функцию закрытия соединения (через делегирование ;hackney_response.close/1) или , просто избавиться от избыточного HTTPoison и просто используйте hackney.

...