Приложение.стоп (...) в оболочке эликсира


Я программирую простое приложение в Elixir, используя Plug and Cowboy and mix. После выполнения:

$ iex -S mix

Приложение запускается. Если я выполню

iex(1)> Application.start(:web)
{:error, {:already_started, :web}}

Я получаю ожидаемый результат. Однако, когда я пытаюсь остановить приложение, используя следующую команду:

iex(2)> Application.stop(:web)
:ok

Я получаю :ok, но затем я получаю много сообщений, включая следующие:

iex(3)>
09:36:43.689 [info]  Application web exited: :stopped

09:36:43.691 [error] GenServer #PID<0.189.0> terminating
** (stop) killed
Last message: {:EXIT, #PID<0.187.0>, :killed}
State: {:state, {#PID<0.189.0>, :ranch_acceptors_sup}


:undefined, 1, 5, [], 0, :ranch_acceptors_sup, [ServeRequests.HTTP, 100, 
:ranch_tcp, [port: 4000]]}
09:36:43.691 [error] Failed to start Ranch listener ServeRequests.HTTP in :ranch_tcp:listen([port: 4000]) for reason :eaddrinuse (address already in use)
09:36:43.691 [info]  Application ranch exited: shutdown
nil

Я делаю что-то не так в коде? Это нормальное поведение?

Содержание mix.exs файл выглядит следующим образом:

defmodule Web.Mixfile do
  use Mix.Project

  def project do
    [app: :web,
     version: "0.1.1",
     elixir: "~> 1.2",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  def application do
    [applications:
        [:logger, :cowboy, :plug],
        mod: {Web, []}
    ]
  end

  defp deps do
  [{:cowboy, "~> 1.0.3"},
  {:plug, "~> 1.1.2"}]
  end
end

Содержание lib/web.ex следующее:

defmodule Web do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      worker(Web.Router, [])
    ]

    opts = [strategy: :one_for_one, name: Web.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Спасибо, Михалис.

2 2

2 ответа:

Это немного субдокументировано в документах, и теперь я также вижу, что я должен был объяснить это в EiA (my bad). Суть в том, что вы должны использовать штекер.Адаптеры.Ковбой.child_spec , Чтобы правильно вставить сервер в дерево наблюдения. Затем сервер будет правильно остановлен с приложением.

Вот как это будет выглядеть в вашем примере (в web.ex):

children = [
  Plug.Adapters.Cowboy.child_spec(:http, Web.Router, [])
]
Таким образом, вы можете полностью избавиться от функций my_web_start и Web.Router.start_server.

Пробуем его в оболочке дает мне:

iex(1)> Application.stop(:web)
:ok
16:44:29.929 [info]  Application web exited: :stopped

iex(2)> Application.start(:web)
:ok

И после этого я снова могу получить доступ к странице.

  • там написано, что ваш адрес уже используется (eaddrinuse).
  • попробуйте перезапустить устройство, на котором вы работаете, или проверьте, что программа не открыта дважды.
  • перезапуск остановит и запустит программу, вероятно, фиксирующую адрес в Воспользуйся.