Приложение.стоп (...) в оболочке эликсира
Я программирую простое приложение в 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 ответа:
Это немного субдокументировано в документах, и теперь я также вижу, что я должен был объяснить это в 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
И после этого я снова могу получить доступ к странице.