如何重新启动崩溃的监督任务

时间:2016-02-16 07:44:59

标签: elixir otp

{:ok, tas} = Task.Supervisor.start_link(restart: :transient, max_restarts: 4)
a = 1
Task.Supervisor.async_nolink(tas, fn -> IO.puts "#{a}..." end)
Task.Supervisor.async_nolink(tas, fn ->
  IO.puts "Not Restarting :( "
  1 = 2
end)
a =  a + 1
Task.Supervisor.async_nolink(tas, fn -> IO.puts "#{a}.." end)
a =  a + 1
Task.Supervisor.async_nolink(tas, fn -> IO.puts "#{a}.." end)

选项restart: :transient似乎没有任何效果。

我执行http请求获取多个资源的任务Task.async(fn(x) -> fetch_info(x) end很少,并且有超时错误。重新尝试那些失败的任务会很好,而不是使用tryrescue

我认为async_nolink是我得到的最接近而没有崩溃的过程。如果没有办法使用Task,我们是否有一个更简单的方法使用Supervisor启动多个进程,这些进程在作业完成后存在,如果失败则重新启动它们?

2 个答案:

答案 0 :(得分:6)

您只需使用Task.Supervisor.start_child代替Task.Supervisor.async_nolink即可正确重启子项:

{:ok, tas} = Task.Supervisor.start_link(restart: :transient, max_restarts: 4)

Task.Supervisor.start_child(tas, fn -> 1 = 2 end) 

答案 1 :(得分:4)

我不认为任务是你想要的最好的选择。在文档Task Docs中,据说:

  

该模块定义了一个主管,可用于动态监督任务。在幕后,这个模块实现为:simple_one_for_one主管,其中工人是临时的(即他们死后不会重新启动)。

  

:restart - 重启策略,可能是:临时(默认),:transient或:permanent。检查Supervisor.Spec了解更多信息。默认为临时,因为崩溃后大多数任务无法有效重启;

您应该调查GenServer并建立一个工作人员池GenServer Intro。 Little Elixir和OTP Guide这本书非常有用,我读了大约一半,它为OTP,发行和监督提供了良好的基础。

编辑:我刚刚检查了这本书,但无法找到有关重新启动任务的任何内容,只是进程。