Elixir shell 中的 Application.stop(...)
Posted
技术标签:
【中文标题】Elixir shell 中的 Application.stop(...)【英文标题】:Application.stop(...) in Elixir shell 【发布时间】:2016-08-22 18:42:07 【问题描述】:我正在使用 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
谢谢, 米哈利斯。
【问题讨论】:
请分享您的mix.exs
配置文件。看起来您的应用程序已正确停止而没有错误(第一行),但您的节点尝试在您的操作系统释放端口 4000 之前立即重新启动牧场。如果您可以在 GitHub 上共享您的整个项目,它将允许人们进行挖掘。
包含mix.exs
的内容。有没有办法释放4000端口或者让Supervisor稍等一下?
@MihalisTsoukalos 你能把lib/web.ex
的内容也发一下吗?
我已经检查过,即使使用 start_permanent
,应用程序在使用 Application.stop/1
停止时也不应该自动重新启动,所以我不确定是否可以提供帮助。
您可以在github.com/mactsouk/Elixir找到该项目的所有Elixir文件。
【参考方案1】:
这在文档中有一些子文档,我现在也看到我应该在 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
然后我可以再次访问该页面。
【讨论】:
我有 EiA,但在那里找不到解决方案。再次感谢!【参考方案2】: 它表示您的地址已被使用 (eaddrinuse)。 尝试重新启动您正在运行的设备或检查您没有两次打开程序。 重新启动将停止并启动可能修复地址的程序 使用。【讨论】:
为什么应用程序无法正常停止?以上是关于Elixir shell 中的 Application.stop(...)的主要内容,如果未能解决你的问题,请参考以下文章
将 iex shell 附加到正在运行的 elixir 应用程序