2016-04-28 23 views
2

我使用Plug and Cowboy编写了一个简单的Elixir应用程序并混合使用。执行后:Elixir Shell中的Application.stop(...)

$ 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 

感谢, Mihalis。

+4

请分享你的'mix.exs'配置文件。它看起来像你的应用程序正常停止没有错误(第一行),但是你的节点试图在你的操作系统发布4000端口之前立即重新启动牧场。如果你可以在GitHub上共享你的整个项目,它将允许人们挖掘。 – tkowal

+0

包含'mix.exs'的内容。有没有办法释放4000端口或让主管等一会? –

+3

@MihalisTsoukalos你还可以发布'lib/web.ex'的内容吗? – Dogbert

回答

2

这是有点subdocumented在文档中,我现在也看到,我应该在EiA(我的坏)解释这一点。要点是您应该使用Plug.Adapters.Cowboy.child_spec将监控树中的服务器正确插入。然后,服务器将被正确停止与应用程序。

下面是它会怎样看你的例子(web.ex):

children = [ 
    Plug.Adapters.Cowboy.child_spec(:http, Web.Router, []) 
] 

有了这一点,你可以完全摆脱的my_web_startWeb.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 

此后,我可以再次访问该页面。

+1

我有EIA,我找不到解决方案。再次感谢! –

-1
  • 它说你的地址已经在使用(eaddrinuse)。
  • 尝试重新启动您正在运行的设备,或者检查是否没有打开该程序两次。
  • 重新启动将停止并启动程序,可能会修复地址 使用。
+0

为什么应用程序无法正常停止? –