如何启动Elixir进程,然后在超时后终止它?我有这样的代码:
defmodule OperationsManager do
def run_operation do
spawn fn ->
# long operation
end
end
end
Run Code Online (Sandbox Code Playgroud)
内部操作可能持续太长时间等待它的结束,所以我需要从管理器中删除该进程.我该怎么做?
编辑:
重要细节:我需要生成几个操作,并且所有操作都应该具有单独的超时.
只是为了完整性:erlang :timer模块有一个功能kill_after,在经过一段时间后会强制终止进程.
# Kill the current process after 2 seconds
:timer.kill_after(:timer.seconds(2))
# Kill pid after 2 minutes
:timer.kill_after(:timer.minutes(2), pid)
Run Code Online (Sandbox Code Playgroud)
我会看一下Elixir Task模块.
您可以使用Task.yield或Task.yield_many在给定时间间隔内执行多个任务来处理单个任务,尽管Task.yield看起来更接近您可能需要的任务.收益率返回{:ok, result}(成功返回),{:exit, reason}(任务崩溃)或:nil(超时间隔超过).您还可以考虑将任务放在监督树中.
以下代码基于elixir 1.2.1.
defmodule OperationsManager do
def run_operation() do
task1 = Task.async(fn() -> operation("task 1", 1) end)
result = Task.yield(task1, 5000)
process_task(task1, result)
task2 = Task.async(fn() -> operation("task 2", 2) end)
task4 = Task.async(fn() -> operation("task 4", 4) end)
task6 = Task.async(fn() -> operation("task 6", 6) end)
task8 = Task.async(fn() -> operation("task 8", 8) end)
results = Task.yield_many([task2, task4, task6, task8], 7000)
for {task, res} <- results do
process_task(task, res)
end
end
def process_task(task, res) do
case res do
:nil ->
IO.write("shutting down timed out task: ")
IO.inspect(task)
Task.shutdown(task, :brutal_kill)
{:ok, task_number} ->
IO.puts("#{task_number} is complete")
{:exit, _reason} ->
# some logic when the task terminates
end
end
def operation(task_number, timeout) do
:timer.sleep(timeout * 1000)
task_number
end
end
OperationsManager.run_operation()
Run Code Online (Sandbox Code Playgroud)