【问题标题】:Starting an app using supervisor in Elixir which would automatically restart on error在 Elixir 中使用 supervisor 启动一个应用程序,它会在出错时自动重启
【发布时间】:2016-11-28 20:47:53
【问题描述】:

我可以在 elixir 上运行应用程序,但如果发生错误,一切都会存在。我只想在这种情况下重新启动我的应用程序。我正在使用主管,但甚至不知道它是否有效。以下是我的代码:-

mix.exs:-

def application do
[ 
  applications: [:httpotion, :zookeeper, :parallel, :poison],
  mod: {ServiceMonitor, []}
]
end

service_monitor.ex

defmodule ServiceMonitor do
  use Application

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

    children = [
        worker(ServiceMonitor.Registry.setup, []),
    ]

    supervise(children, strategy: :one_for_one)
  end
end

registry.ex

defmodule ServiceMonitor.Registry do

  def setup do
    zk = get_zk
    start(zk)
  end

  def start(zk) do
    #main code
  end
end

现在我正在使用以下命令运行我的应用程序:-

MIX_ENV=test mix run

这一切都运行良好,直到我在我的主代码中收到错误。应用程序存在并且永远不会重新启动。我收到的错误是:-

** (Mix) Could not start application service_monitor: exited in: ServiceMonitor.start(:normal, [])
** (EXIT) exited in: Task.await(%Task{owner: #PID<0.164.0>, pid: #PID<0.169.0>, ref: #Reference<0.0.2.1026>}, 3600000)
    ** (EXIT) an exception was raised:
        ** (MatchError) no match of right hand side value: {:error, :no_node}
            (service_monitor) lib/service_monitor/registry.ex:121: anonymous fn/3 in ServiceMonitor.Registry.remove_available_if_not_registered/3
            (elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
            (elixir) lib/task/supervised.ex:40: Task.Supervised.reply/5
            (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

请帮忙看看我哪里出错了。我的要求是应用程序应在收到错误后立即自动重启。

【问题讨论】:

  • 这行得通吗:worker(ServiceMonitor.Registry, [], function: :setup)?如果没有,你能把ServiceMonitor.Registry.start/1的内容发一下吗?
  • 不,这也给出了同样的错误。 start 函数是这样的:- def start(zk) do #some code start(zk) end 基本上是一个无限循环

标签: task elixir erlang-supervisor


【解决方案1】:

如果ServiceMonitor是你的Supervisor模块,它应该使用Supervisor而不是根据this导入Supervisor.spec

编辑: 如果您仍想与您的主管一起工作,请尝试在代码末尾添加Supervisor.start,就像示例中一样:

defmodule KVServer do
  use Application

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

    children = [
    # worker(KVServer.Worker, [arg1, arg2, arg3])
    ]

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

【讨论】:

  • 如果我这样做,它会显示** (CompileError) lib/service_monitor.ex:11: undefined function worker/3
  • 删除此use Application 并粘贴use Supervisor。您也不应该在函数中导入 Supervisor.spec 。还有函数的名称,其中将调用worker/3 应该是init
  • 现在当我使用 MIX_ENV=test mix run 运行我的应用程序时,我收到错误:- ** (Mix) Could not start application service_monitor: exited in: ServiceMonitor.start(:normal, []) ** (EXIT) an exception was raised: ** (UndefinedFunctionError) undefined function ServiceMonitor.start/2
  • 我已经完全按照您在编辑的答案defmodule ServiceMonitor do use Application def start(_type, _args) do import Supervisor.Spec, warn: false children = [ worker(ServiceMonitor.Registry, [], function: :setup), ] opts = [strategy: :one_for_one, name: ServiceMonitor.Supervisor] Supervisor.start_link(children, opts) end end 中所说的做了,但我仍然遇到同样的错误
  • 这个函数只是返回zookeeper客户端,所以我上面没有写。基本上是:-def get_zk do case ZK.start(@zk_quorams) do {:ok, zk} -&gt; zk end end
猜你喜欢
  • 2015-12-08
  • 1970-01-01
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 2016-07-31
相关资源
最近更新 更多