{: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
很少,并且有超时错误。重新尝试那些失败的任务会很好,而不是使用try
,rescue
。
我认为async_nolink
是我得到的最接近而没有崩溃的过程。如果没有办法使用Task
,我们是否有一个更简单的方法使用Supervisor
启动多个进程,这些进程在作业完成后存在,如果失败则重新启动它们?
答案 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,发行和监督提供了良好的基础。