Application.stop(...) 在长生不老药中 shell
Application.stop(...) in Elixir shell
我正在使用 Plug 和 Cowboy 并混合使用 Elixir 编写一个简单的应用程序。执行后:
$ 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
谢谢,
米哈利斯.
- 它说您的地址已被使用 (eaddrinuse)。
- 尝试重新启动您 运行 使用的设备,或者检查您是否没有打开该程序两次。
- 重新启动将停止并启动程序,可能会修复 Address In
使用.
这在文档中有点子记录,我现在也看到我应该在 EiA 中解释这个(我的错)。要点是您应该使用 Plug.Adapters.Cowboy.child_spec 将服务器正确插入监督树中。然后,服务器将随应用程序正确停止。
这是您的示例(在 web.ex
中)的样子:
children = [
Plug.Adapters.Cowboy.child_spec(:http, Web.Router, [])
]
这样,您就可以完全摆脱 my_web_start
和 Web.Router.start_server
功能。
在 shell 中尝试它给我:
iex(1)> Application.stop(:web)
:ok
16:44:29.929 [info] Application web exited: :stopped
iex(2)> Application.start(:web)
:ok
之后我可以再次访问该页面。
我正在使用 Plug 和 Cowboy 并混合使用 Elixir 编写一个简单的应用程序。执行后:
$ 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
谢谢, 米哈利斯.
- 它说您的地址已被使用 (eaddrinuse)。
- 尝试重新启动您 运行 使用的设备,或者检查您是否没有打开该程序两次。
- 重新启动将停止并启动程序,可能会修复 Address In 使用.
这在文档中有点子记录,我现在也看到我应该在 EiA 中解释这个(我的错)。要点是您应该使用 Plug.Adapters.Cowboy.child_spec 将服务器正确插入监督树中。然后,服务器将随应用程序正确停止。
这是您的示例(在 web.ex
中)的样子:
children = [
Plug.Adapters.Cowboy.child_spec(:http, Web.Router, [])
]
这样,您就可以完全摆脱 my_web_start
和 Web.Router.start_server
功能。
在 shell 中尝试它给我:
iex(1)> Application.stop(:web)
:ok
16:44:29.929 [info] Application web exited: :stopped
iex(2)> Application.start(:web)
:ok
之后我可以再次访问该页面。