HTTPoison ArgumentError в задаче микширования Phoenix

У меня есть задача микширования mix fetch.btc в приложении phoenix (lib/mix/tasks/fetch.btc.ex):

defmodule Mix.Tasks.Fetch.Btc do
  use Mix.Task

  def run(_args) do
    res = HTTPoison.get!("https://blockchain.info/ticker")
    IO.inspect(res)
  end
end

Когда я запускаю mix fetch.btc, я получаю сообщение об ошибке:

** (ArgumentError) argument error
    (stdlib) :ets.lookup_element(:hackney_config, :mod_metrics, 2)
    PROJ_DIR/deps/hackney/src/hackney_metrics.erl:27: :hackney_metrics.get_engine/0
    PROJ_DIR/deps/hackney/src/hackney_connect.erl:78: :hackney_connect.create_connection/5
    PROJ_DIR/deps/hackney/src/hackney_connect.erl:47: :hackney_connect.connect/5
    PROJ_DIR/deps/hackney/src/hackney.erl:330: :hackney.request/5
    lib/httpoison/base.ex:787: HTTPoison.Base.request/6
    lib/httpoison.ex:128: HTTPoison.request!/5
    lib/mix/tasks/fetch.btc.ex:14: Mix.Tasks.Fetch.Btc.run/1
    (mix) lib/mix/task.ex:331: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:79: Mix.CLI.run_task/2
    (elixir) lib/code.ex:767: Code.require_file/2

Но в моем контроллере этот код res = HTTPoison.get!("https://blockchain.info/ticker") работает успешно!

Информация:

hackney: 1.15.1
httpoison: 1.5.0
phoenix: 1.4.3
  1. Что я делаю не так?
  2. Как правильно сделать http-запрос в микс-задаче?

person Alexey Egorov    schedule 02.05.2019    source источник


Ответы (2)


Код в вашем контроллере запускается, когда приложение и все его зависимости уже запущены. mix задачи выполняются в :mix приложении, которое, очевидно, не запускает :hackney по умолчанию.

Все, что вам нужно, это убедиться, что он запущен / запустить его вручную:

def run(_args) do
  # ⇓⇓⇓⇓⇓⇓⇓ THIS ⇓⇓⇓⇓⇓⇓⇓
  Application.ensure_all_started(:hackney)
  # ⇑⇑⇑⇑⇑⇑⇑ THIS ⇑⇑⇑⇑⇑⇑⇑

  res = HTTPoison.get!("https://blockchain.info/ticker")
  IO.inspect(res)
end
person Aleksei Matiushkin    schedule 02.05.2019
comment
спасибо за помощь! Это работает! Где я могу прочитать больше информации об этом для большего понимания? - person Alexey Egorov; 02.05.2019
comment
О OTP, деревьях наблюдения и как работает виртуальная машина erlang? В Интернете полно ресурсов. Я не решаюсь предложить что-то особенное, проверьте официальный список erlang.org/faq/obtaining.html - person Aleksei Matiushkin; 02.05.2019

Вы также можете использовать HTTPoison.start() перед фактическим вызовом. Это также будет работать, если вы не хотите запускать приложение hackney каждый раз в микс-файле или если вы не хотите начинать использовать приложение.

person Zubair Nabi    schedule 02.05.2019
comment
что на самом деле происходит, когда мы вызываем HTTPoison.start()? - person Alexey Egorov; 02.05.2019
comment
HTTPoison это OSS, ради бога. https://github.com/edgurgel/httpoison/blob/master/lib/httpoison/base.ex#L216 - person Aleksei Matiushkin; 02.05.2019
comment
@ZubairNabi неверно. Проверьте ссылку, которую я разместил выше: она запускает не только необходимое :hackney приложение, но и весь зоопарк. включая сам :httpoison и все его зависимости. Ну, зависимости :hackney только, но все же. - person Aleksei Matiushkin; 02.05.2019
comment
на самом деле он делает то, что сделал @AlekseiMatiushkin. Запускает приложение Httpoison и его зависимости. - person Zubair Nabi; 02.05.2019
comment
@AlekseiMatiushkin понял. да, Httpoison.start запускает все приложения, однако для конкретной проблемы пользователей он может запускать только «хакни». Спасибо :+1 - person Zubair Nabi; 02.05.2019