如何用流捕获进程的错误?

时间:2017-08-30 13:17:58

标签: elixir

我正在将CSV导入数据库,我解析它并处理每个条目:

stream= File.stream!(path)
    |> CSVParser.parse_stream
    |> Stream.map(fn row ->
      case row do
        [_] -> nil
         _  -> row
      end
      end)
    |> Stream.chunk(chunck_n, step, [])
    |> Task.async_stream(CsvsController, :chunk_handler_fn, [process_name, db_map, entity_name, entity_id, entity_ios2, table_name, invite?, background_job_id], max_concurrency: 10)



Task.start_link(Stream, :run, [stream])

会有数百个块,通过CsvsController处理但是如何捕获会阻止当前进程的错误?因为Task.start_link与当前流程相关联。

1 个答案:

答案 0 :(得分:0)

Task链接到您的流程后,此流程将收到带有签名:DOWN的{​​{1}}信息消息。假设此代码在{:DOWN, _, :process, _pid, _reason}内,您可能只是实现处理程序:

GenServer

在那里做任何你想做的事。

def handle_info({:DOWN, _, :process, _pid, _reason}, state) do ... end 处理此问题的示例(不完整,但您明白了):

GenServer

现在您要将它放入监督树中,并在需要时拨打defmodule CsvImporter do use GenServer def start_link(_opts \\ []) do GenServer.start_link(__MODULE__, %{}, name: __MODULE__) end def process!(path), do: GenServer.call(__MODULE__, {:process, path}) def handle_call({:process, path}, _from, state) do stream = path |> File.stream!() |> CSVParser.parse_stream() ..... {:ok, pid} = Task.start_link(Stream, :run, [stream]) {:reply, pid, state} end def handle_info({:DOWN, _, :process, _pid, reason}, state) do # check **reason** for whether it was finished # unexpectedly and do something end end

我越想到这一点,我就越相信你实际上根本不需要任务。只需CsvImporter.process!(path)到此castGenServer本身(GenServer s的处理就是异步),您就已经完成了设置。