HTTPoison закрыть соединение вручную

Это очень простой модуль, который постоянно проверяет 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

person Nema Ga    schedule 18.03.2019    source источник


Ответы (2)


Из HTTPoison README:

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

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

А пока вы можете позвонить hackney_pool:stop_pool(:default). Очевидно, что это в любом случае не оптимальное решение и связано с огромными накладными расходами. Поэтому я бы посоветовал либо предоставить запрос на включение HTTPoison, чтобы включить функцию закрытия соединения (путем делегирования _ 6_) или просто избавьтесь от лишних HTTPoison и просто используйте hackney.

person Aleksei Matiushkin    schedule 18.03.2019

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

HTTPoison.get(url, [], [
  timeout: 5_000,
  recv_timeout: 5_000,
  proxy: proxy,
  hackney: [pool: false],
  ssl: [{:versions, [:'tlsv1.2']}]
])
person Nema Ga    schedule 18.03.2019
comment
Таким образом вы в основном делаете свой код однопоточным, чего не ожидают от erlang большинство людей. - person Aleksei Matiushkin; 19.03.2019
comment
@AlekseiMatiushkin, пожалуйста, объясните? Я создал кучу несвязанных процессов, каждый из которых выполняет приведенный выше код и отправляет результаты обратно. Не уверен, что это правильное многопоточное выполнение, но оно работает. - person Nema Ga; 20.03.2019
comment
@AlekseiMatiushkin отключение пула не означает, что он однопоточный, он все равно будет создавать отдельные соединения, он просто не поддерживает их. - person Johanna Larsson; 20.03.2019