Elixir 长生不老药工艺极限?

Elixir 长生不老药工艺极限?,elixir,phoenix-framework,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, :

我想创建一个类似以下内容的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
假设:

  • 爬行
    功能将创建另一个3
    任务
  • 每个
    爬行
    工作人员可能会花费3秒钟的时间运行
  • 队列
    可能有数百万条消息

  • 我怎么知道并行过程对长生不老药的限制是什么?我如何管理它不中断?

    我建议为此使用
    Task.async\u stream
    <代码>任务。异步_流允许您并行处理流,同时限制并行运行的任务数量。在Erlang 20中,进程数的默认限制是262144,但如果要对站点进行爬网,可能需要一个更低的限制

    您可以使用
    stream.iterate
    ,从不断返回新项目的函数创建流:

    stream =
      Stream.iterate(next_from_queue(), fn _ -> next_from_queue() end)
      |> Stream.take_while(fn {:ok, _} -> true; {:error, :empty} -> false end)
    
    由于您希望在
    {:error,:empty}
    处停止,因此我们使用

    然后像这样使用
    Task.async\u stream

    stream
    |> Task.async_stream(fn {:ok, queue_msg} ->
      crawling(queue_msg)
    end, max_concurrency: 16)
    

    这将并行运行最多16个任务的流。最终结果将是
    爬网(queue\u msg)

    所有返回值的列表,谢谢@Dogbert的回复!!!我真的很喜欢你的方法。然而,我希望有一个长生不老药架构,其中的代码可以爆炸100%的CPU和内存。您认为这是一种好方法吗?spawns有许多进程,然后捕获“限制已达到异常”?不幸的是@AugustoPedraza,当达到BEAM虚拟机可以处理的限制时,不会出现“引发异常”的情况。它只会崩溃。你为什么不利用它呢?它提供了一种背压机制,在这种机制中,消费者只会要求生产者提供更多可用的任务。您可以对其进行配置,以便在需要完成更多工作时动态生成消费者。通过这种方式,你可以最大限度地利用你的资源,而不会爆炸。可以这么说。@KevinJohnson GenStage看起来太棒了!!!然而,如果我没有弄错的话,为了“消费”我的生产者(队列)得到的东西,我需要“初始化”生产者。因此,我希望您能帮助我解决以下问题:-我是否需要初始化多个生产者以达到更高的并行性?-我可以动态地这样做吗?我的意思是当我在消费者身上有更多的“等待”工作时,创造更多的生产者。。。提前谢谢!