Elixir工艺限制?

时间:2017-12-07 14:49:48

标签: elixir phoenix-framework

我想创建一个类似于此的Elixir代码:

def infinite_loop(created_workers \\ []) do
  case next_from_queue do
    {:ok, queue_msg} ->
      new_worker = Task.async(fn -> crawling(queue_msg) end)
      infinite_loop([new_worker | created_workers])
    {:error, :empty} ->
      created_workers.map(&Task.await/1)
  end
end

假设:

  1. crawling功能会创建另外3个Task
  2. 每个crawling 工作人员可能会花费3秒钟
  3. queue可能有数百万条消息
  4. 我怎么知道Elixir上并行处理的限制是什么?如何管理它以免中断?

1 个答案:

答案 0 :(得分:6)

我建议您使用Task.async_streamStream.iterate允许您并行处理流,同时限制并行运行的任务数。虽然Erlang 20中进程数的默认限制为262144,但如果您正在抓取某个网站,则可能需要更低的限制。

您可以使用stream = Stream.iterate(next_from_queue(), fn _ -> next_from_queue() end) |> Stream.take_while(fn {:ok, _} -> true; {:error, :empty} -> false end)

继续返回新项目的函数创建流
{:error, :empty}

由于您希望停留在Stream.take_while,我们会使用Task.async_stream停止播放。

然后像这样使用stream |> Task.async_stream(fn {:ok, queue_msg} -> crawling(queue_msg) end, max_concurrency: 16)

crawling(queue_msg)

这将并行运行最多16个任务的流。最终结果将是{{1}}的所有返回值的列表。