我有Elixir Task,需要一些时间(10秒)。当应用程序升级时,尽管Task.Supervisor
:
shutdown: 30000
终止
=SUPERVISOR REPORT==== 13-Aug-2015::00:03:09 ===
Supervisor: {local,tasks_sup}
Context: child_terminated
Reason: killed
Offender: [{pid,<0.304.0>},
{id,'Elixir.Task.Supervised'},
{mfargs,{'Elixir.Task.Supervised',start_link,undefined}},
{restart_type,temporary},
{shutdown,30000},
{child_type,worker}]
我不知道如何在应用程序升级时优雅地停止任务(等到任务完成)。以下是描述我的问题的代码:
defmodule MyApp do
use Application
def start(_, _) do
MyApp.Supervisor.start_link([])
end
end
defmodule MyApp.Supervisor do
use Supervisor
def start_link(state) do
Supervisor.start_link(__MODULE__, state, name: __MODULE__)
end
def init(state) do
children = [
supervisor(Task.Supervisor, [[name: :tasks_sup, shutdown: 30000]]),
worker(MyApp.Worker, [state], restart: :permanent)
]
supervise(children, strategy: :one_for_one)
end
end
defmodule MyApp.Worker do
def start_link(state) do
GenServer.start_link(__MODULE__, state, [name: MyApp.Worker])
end
def init(state) do
{:ok, state}
end
def handle_call(:which_children, _, state) do
children = [{Task.Supervisor, :tasks_sup, :supervisor, [Task.Supervisor]}]
{:reply, children, state}
end
def handle_info({:task, data}, state) do
Task.Supervisor.async(:tasks_sup, MyApp.TaskRunner, :perform, [data])
end
def handle_info(_, state) do
{:noreply, state}
end
end
defmodule MyApp.TaskRunner do
def perform(data) do
# some 10 secs job
end
end
是否有任何想法或假设如何等到MyApp.TaskRunner.perform
完成然后允许停止任务?
对我来说如何处理任务并不重要:使用原生Elixir的Task
或通过自己的一些TaskProcessor模块。
Task.Supervisor.async
将任务链接到调用者,这可能是个问题。但是,我使用async
和start_link
尝试了几次不同的情况,每次都得到相同的结果。我的最新测试是:
children = [
supervisor(Task.Supervisor, [[name: :tasks_sup, shutdown: 30000]]),
worker(MyApp.Worker, [state], restart: :permanent)
]
supervise(children, strategy: :one_for_one)
和
Task.Supervisor.start_child(:tasks_sup, MyApp.TaskRunner, :perform, [data])
工人在大约2-3秒后被杀。
答案 0 :(得分:1)
链接可能是将您的任务降低的链接。因为工作人员调用For Each tagsx In tags2
If tagsx.ID = "filterBtn" Then
tagsx.Click
Do Until Not IE.Busy
DoEvents
Loop
End If
Next tagsx
,所以它会将任务链接到您的工作人员。该工作程序的超时时间为5000毫秒,因此它将在主管之前关闭,从而终止任务。您可以通过设置之前的报告来确认。
顺便说一句,如果您稍后通过相同的流程致电Task.Supervisor.async
,则应该只拨打async
,而且此处似乎并非如此。您可能应该调用await
(因此任务没有链接到调用者)。
您的函数被杀的另一个可能原因是VM只保留最新的两个代码模块版本。如果您在短时间间隔内升级两次,旧版本将被清除,其运行进程将被终止。