如何重新启动崩溃的受监督任务
How to restart a supervised task that crashes
{: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
似乎没有任何作用。
我有几个任务 Task.async(fn(x) -> fetch_info(x) end
发出 http 请求以获取多个资源,并且出现超时错误。最好重试那些失败的任务,而不是使用 try
、rescue
。
我认为 async_nolink
是我在没有使进程崩溃的情况下得到的最接近的结果。如果没有办法使用 Task
,我们是否有更简单的方法使用 Supervisor
启动多个进程,一旦他们的工作完成就存在,如果他们失败就重新启动它们?
我认为 Tasks 不是您想要的最佳选择。在文档 Task Docs 中说:
This module defines a supervisor which can be used to dynamically supervise tasks. Behind the scenes, this module is implemented as a :simple_one_for_one supervisor where the workers are temporary (i.e. they are not restarted after they die).
和
:restart - the restart strategy, may be :temporary (the default), :transient or :permanent. Check Supervisor.Spec for more info. Defaults to temporary as most tasks can’t be effectively restarted after a crash;
您应该研究 GenServer
并建立一个工人池 GenServer Intro。 Little Elixir and OTP Guide 这本书在这方面很不错,我读了大约一半,它为 OTP、分发和主管提供了良好的基础。
编辑:我刚刚查看了这本书,找不到任何关于重新启动任务的信息,只有进程。
您只需使用 Task.Supervisor.start_child
而不是 Task.Supervisor.async_nolink
即可正确重新启动 children:
{:ok, tas} = Task.Supervisor.start_link(restart: :transient, max_restarts: 4)
Task.Supervisor.start_child(tas, fn -> 1 = 2 end)
{: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
似乎没有任何作用。
我有几个任务 Task.async(fn(x) -> fetch_info(x) end
发出 http 请求以获取多个资源,并且出现超时错误。最好重试那些失败的任务,而不是使用 try
、rescue
。
我认为 async_nolink
是我在没有使进程崩溃的情况下得到的最接近的结果。如果没有办法使用 Task
,我们是否有更简单的方法使用 Supervisor
启动多个进程,一旦他们的工作完成就存在,如果他们失败就重新启动它们?
我认为 Tasks 不是您想要的最佳选择。在文档 Task Docs 中说:
This module defines a supervisor which can be used to dynamically supervise tasks. Behind the scenes, this module is implemented as a :simple_one_for_one supervisor where the workers are temporary (i.e. they are not restarted after they die).
和
:restart - the restart strategy, may be :temporary (the default), :transient or :permanent. Check Supervisor.Spec for more info. Defaults to temporary as most tasks can’t be effectively restarted after a crash;
您应该研究 GenServer
并建立一个工人池 GenServer Intro。 Little Elixir and OTP Guide 这本书在这方面很不错,我读了大约一半,它为 OTP、分发和主管提供了良好的基础。
编辑:我刚刚查看了这本书,找不到任何关于重新启动任务的信息,只有进程。
您只需使用 Task.Supervisor.start_child
而不是 Task.Supervisor.async_nolink
即可正确重新启动 children:
{:ok, tas} = Task.Supervisor.start_link(restart: :transient, max_restarts: 4)
Task.Supervisor.start_child(tas, fn -> 1 = 2 end)